예제 #1
0
def runall(prefixes,cat):
    for prefix in prefixes:
	images=glob.glob(prefix)
	iraf.imgets(images[0],'FILTER')
	filter=str(iraf.imgets.value)

	for im in images:
	    runsextractor(im)

	    t=im.split('.')
	    if cat < 0.1:
		out='sdssmatch-'+str(t[0])
		refcat='sdsscoords.dat'
		s='cat '+out+' >> sdssmatch'+filter
		plotsdsspos(im)
	    if cat > .1:
		out='2massmatch-'+str(t[0])
		refcat='2masscoords.dat'
		s='cat '+out+' >> 2massmatch'+filter
		plot2masspos(im)
	    #iraf.xyxymatch(input='testxy.cat',reference='sdsscoords.dat',output=out,tolerance=20.,refpoints='refpoints',interactive='yes')
	    iraf.xyxymatch(input='testxy.cat',reference=refcat,output=out,tolerance=10.,refpoints='refpoints',interactive='no')
	    os.system(s)

	infile='sdssmatch'+filter
	infile='2massmatch'+filter
	iraf.geomap(input=infile,database='PiscesBok',transform=filter,xmin=1.,xmax=1024,ymin=1.,ymax=1024.)
예제 #2
0
 def source_match(self):
     '''
     Uses iraf.xyxymatch to match sources between images.
     '''
     
     countlist = glob.glob(self.root + '/*counts.fits')
     sourcelist = glob.glob(self.root + '/*sources.dat')
     refimage = sourcelist[0]
     
     for image, source in zip(countlist, sourcelist):
         iraf.xyxymatch(input=source, reference=refimage, \
                        output=image[:-12] + '_match.dat', \
                        tolerance=self.tolerance, verbose='no')
예제 #3
0
def twomassmatch():
    twomassRA, twomassDec, mag, lineno, octRA, octDec, octlineno, octflux, chipno = [], [], [], [], [], [], [], [], []
    global bandline, indexjhk
    with open('2mass.txt', 'r') as f:
        lines = f.readlines()
        i = 1
        for x in lines:
            line = x.split()
            if x.startswith('#') == False and x.split()[21][indexjhk] == '0' \
                    and x.split()[23] == '0' and x.split()[24] == '0' \
                    and (x.split()[18][indexjhk] == 'A' or x.split()[18][indexjhk] == 'B'):
                twomassRA.append(float(line[0]) * 1000)
                twomassDec.append(float(line[1]) * 1000)
                mag.append("#" + line[bandline])
                lineno.append("#" + str(i))
                i += 1

    ascii.write([twomassRA, twomassDec, mag, lineno],
                '2mass_RADec.txt',
                names=('#RA', 'Dec', 'Mag', 'Line number'),
                overwrite=True)
    with open('oct_total.txt', 'r') as f:
        lines = f.readlines()
        for x in lines:
            line = x.split(' ')
            octRA.append(float(line[len(line) - 3]) * 1000)
            octDec.append(float(line[len(line) - 2]) * 1000)
            octlineno.append(line[0])
            octflux.append(line[convergeap])
            chipno.append(line[len(line) - 1])

    ascii.write([octRA, octDec, octlineno, chipno, octflux],
                'Oct_RADec.txt',
                names=('#RA', 'Dec', 'line', 'chip', 'flux'),
                overwrite=True)
    iraf.xyxymatch(input='Oct_RADec.txt',
                   reference='2mass_RADec.txt',
                   output="2mass_Oct_matched.txt",
                   tolerance=3,
                   verbose="no",
                   xref=0,
                   yref=0,
                   xin=0,
                   yin=0)
예제 #4
0
def get_align_to_subaru(sci='M0416_Ks_c1_mp_avg.fits',
                        wht='M0416_Ks_c1_mp_exp.fits',
                        field='',
                        clean=True,
                        toler=3,
                        verbose=False,
                        fitgeometry='shift',
                        shift_max=20,
                        rms_max=1.1,
                        rot_max=2,
                        rot_only=True,
                        THRESH=2,
                        align_data=None):
    """
    Align HAWK-I images to the FF Subaru astrometric reference catalogs
    """

    #sci='M0416_Ks_c1_mp_avg.fits'; wht='M0416_Ks_c1_mp_exp.fits'

    ### Make object catalog
    se = threedhst.sex.SExtractor()
    se.aXeParams()
    se.copyConvFile()
    se.overwrite = True
    se.options['CHECKIMAGE_TYPE'] = 'NONE'
    if wht is None:
        se.options['WEIGHT_TYPE'] = 'NONE'
    else:
        se.options['WEIGHT_TYPE'] = 'MAP_WEIGHT'
        se.options['WEIGHT_IMAGE'] = wht

    se.options['FILTER'] = 'Y'

    se.options['DETECT_THRESH'] = '%d' % (THRESH)
    se.options['ANALYSIS_THRESH'] = '%d' % (THRESH)
    se.options['MAG_ZEROPOINT'] = '26.0'

    #### Run SExtractor on direct and alignment images
    ## direct image
    se.options['CATALOG_NAME'] = 'direct.cat'
    status = se.sextractImage(sci)
    threedhst.sex.sexcatRegions('direct.cat', 'direct.reg', format=2)

    directCat = threedhst.sex.mySexCat('direct.cat')

    #### Get the X/Y coords of the reference catalog
    #head = pyfits.getheader(sci, 0)
    #wcs = pywcs.WCS(head)
    if 'M0416' in sci:
        ra_list, dec_list, mag = np.loadtxt(
            os.getenv('HAWKI') +
            '/FrontierFields/HST/hlsp_frontier_subaru_suprimecam_macs0416-astrom_R_v1_cat.txt',
            unpack=True)
        if ('c4' in sci):
            ra_list, dec_list, mag = np.loadtxt(
                os.getenv('HAWKI') +
                '/FrontierFields/HST/M0416/macs0416_f814w_radec.cat',
                unpack=True)
    #
    if 'M0717' in sci:
        ra_list, dec_list, mag = np.loadtxt('subaru.radec', unpack=True)

    if ('M1149' in sci) | (field == 'M1149'):
        ra_list, dec_list, mag = np.loadtxt(
            '/Users/brammer/Research/VLT/HAWKI/MACS1149/hlsp_frontier_subaru_suprimecam_macs1149-astrom_R_v1_cat.txt',
            unpack=True)

    if 'A2744' in sci:
        ra_list, dec_list, mag = np.loadtxt(
            os.getenv('HAWKI') +
            '/FrontierFields/HST/hlsp_frontier_subaru_suprimecam_abell2744-astrom_i_v1_cat.txt',
            unpack=True)
        if ('c1' in sci) | ('c4' in sci):
            ra_list, dec_list, mag = np.loadtxt(
                os.getenv('HAWKI') +
                '/FrontierFields/HST/abell2744_f814w_radec.cat',
                unpack=True)

    if align_data is not None:
        ra_list, dec_list, mag = align_data

    im = pyfits.open(sci)
    print sci

    sh = im[0].shape
    head = im[0].header
    head['CUNIT1'] = 'deg'
    head['CUNIT2'] = 'deg'
    wcs = pywcs.WCS(head)

    x_image, y_image = wcs.wcs_sky2pix(ra_list, dec_list, 1)

    try:
        x_image, y_image = wcs.wcs_sky2pix(ra_list, dec_list, 1)
    except:
        x_image, y_image = wcs.wcs_world2pix(ra_list, dec_list, 1)

    ok = (x_image > 0) & (y_image > 0) & (x_image < sh[1]) & (y_image < sh[1])

    x_image, y_image = x_image[ok], y_image[ok]

    fpr = open('align.reg', 'w')
    fpr.write('image\n')
    for i in range(ok.sum()):
        fpr.write('circle(%.6f, %.6f,0.3") # color=magenta\n' %
                  (x_image[i], y_image[i]))
    fpr.close()

    # x_image, y_image = [], []
    #
    # for ra, dec in zip(ra_list, dec_list):
    #     x, y = wcs.wcs_sky2pix([[ra, dec]], 1)[0]
    #     if (x > 0) & (y > 0) & (x < sh[1]) & (y < sh[1]):
    #         x_image.append(x)
    #         y_image.append(y)

    alignCat = catIO.EmptyCat()
    alignCat['X_IMAGE'] = np.array(x_image)
    alignCat['Y_IMAGE'] = np.array(y_image)

    xshift = 0
    yshift = 0
    rot = 0
    scale = 1.

    xrms = 2
    yrms = 2

    NITER = 5
    IT = 0
    while (IT < NITER):
        IT = IT + 1

        #### Get x,y coordinates of detected objects
        ## direct image
        fp = open('direct.xy', 'w')
        for i in range(len(directCat.X_IMAGE)):
            fp.write('%s  %s\n' % (directCat.X_IMAGE[i], directCat.Y_IMAGE[i]))
        fp.close()

        ## alignment image
        fp = open('align.xy', 'w')
        for i in range(len(alignCat.X_IMAGE)):
            fp.write('%s  %s\n' % (np.float(alignCat.X_IMAGE[i]) + xshift,
                                   np.float(alignCat.Y_IMAGE[i]) + yshift))
        fp.close()

        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        #### iraf.xyxymatch to find matches between the two catalogs
        pow = toler * 1.
        try:
            os.remove('align.match')
        except:
            pass
        status1 = iraf.xyxymatch(input="direct.xy",
                                 reference="align.xy",
                                 output="align.match",
                                 tolerance=2**pow,
                                 separation=0,
                                 verbose=iraf.yes,
                                 Stdout=1)

        nmatch = 0
        while status1[-1].startswith('0') | (nmatch < 10) | (float(
                status1[-3].split()[1]) > 40):
            pow += 1
            os.remove('align.match')
            status1 = iraf.xyxymatch(input="direct.xy",
                                     reference="align.xy",
                                     output="align.match",
                                     tolerance=2**pow,
                                     separation=0,
                                     verbose=iraf.yes,
                                     Stdout=1)
            #
            nmatch = 0
            for line in open('align.match').xreadlines():
                nmatch += 1

        if verbose:
            for line in status1:
                print line

        #### Compute shifts with iraf.geomap
        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        try:
            os.remove("align.map")
        except:
            pass

        status2 = iraf.geomap(input="align.match",
                              database="align.map",
                              fitgeometry=fitgeometry,
                              interactive=iraf.no,
                              xmin=iraf.INDEF,
                              xmax=iraf.INDEF,
                              ymin=iraf.INDEF,
                              ymax=iraf.INDEF,
                              maxiter=10,
                              reject=2.0,
                              Stdout=1)
        if verbose:
            for line in status2:
                print line

        #fp = open(root+'.iraf.log','a')
        #fp.writelines(status1)
        #fp.writelines(status2)
        #fp.close()

        #### Parse geomap.output
        fp = open("align.map", "r")
        for line in fp.readlines():
            spl = line.split()
            if spl[0].startswith('xshift'):
                xshift += float(spl[1])
            if spl[0].startswith('yshift'):
                yshift += float(spl[1])
            if spl[0].startswith('xrotation'):
                rot = float(spl[1])
            if spl[0].startswith('xmag'):
                scale = float(spl[1])
            if spl[0].startswith('xrms'):
                xrms = float(spl[1])
            if spl[0].startswith('yrms'):
                yrms = float(spl[1])

        fp.close()

        #os.system('wc align.match')
        print 'Shift iteration #%d, xshift=%f, yshift=%f, rot=%f, scl=%f (rms: %5.2f,%5.2f)' % (
            IT, xshift, yshift, rot, scale, xrms, yrms)

    os.system(
        'cat align.match | grep -v "\#" | grep [0-9] | awk \'{print "circle(", $1, ",", $2, ",4) # color=green"}\' > d.reg'
    )
    os.system(
        'cat align.match | grep -v "\#" | grep [0-9] | awk \'{print "circle(", $3, ",", $4, ",4) # color=magenta"}\' > a.reg'
    )

    shutil.copy('align.map', sci.replace('.fits', '.align.map'))
    shutil.copy('align.match', sci.replace('.fits', '.align.match'))

    #### Cleanup
    if clean:
        rmfiles = [
            'align.cat', 'align.map', 'align.match', 'align.reg', 'align.xy',
            'direct.cat', 'direct.reg', 'direct.xy'
        ]

        for file in rmfiles:
            try:
                os.remove(file)
            except:
                pass

    fp = open(sci.replace('.fits', '.align.info'), 'w')
    fp.write('# image xshift yshift rot scale xrms yrms\n')
    fp.write('%s %.3f %.3f %.4f %.4f %.3f %.3f\n' %
             (sci, xshift, yshift, rot, scale, xrms, yrms))

    if (np.abs(xshift) > shift_max) | (np.abs(yshift) > shift_max) | (
            xrms > rms_max) | (yrms > rms_max):
        print 'Shifts out of allowed range.  Run again with increased shift_max to accept.'
        #return xshift, yshift, rot, scale, xrms, yrms
        ## Add a small shift that should come out easily with another
        ## shift iteration
        xshift, yshift, rot, scale, xrms, yrms = 2, 2, 0, 1.0, -99, -99

    for file in [sci, wht]:
        if ('r' in fitgeometry) & rot_only:
            xshift, yshift = 0, 0

        #apply_offsets(file, [[xshift, yshift, rot, scale]])
        from drizzlepac import updatehdr
        updatehdr.updatewcs_with_shift(file,
                                       sci,
                                       wcsname='DRZWCS',
                                       rot=rot,
                                       scale=scale,
                                       xsh=xshift,
                                       ysh=yshift,
                                       fit=None,
                                       xrms=xrms,
                                       yrms=yrms,
                                       verbose=False,
                                       force=True,
                                       sciext=0)

    if '_dr' in sci:
        im = pyfits.open(sci)
        h = im[0].header
        for i in range(h['NDRIZIM']):
            flt_str = h['D%03dDATA' % (i + 1)]
            if 'sci,2' in flt_str:
                continue
            #
            flt_im = flt_str.split('[')[0]
            ext = int(flt_str.split('[')[1][:-1].split(',')[1])
            updatehdr.updatewcs_with_shift(flt_im,
                                           sci,
                                           wcsname='GTWEAK',
                                           rot=rot,
                                           scale=scale,
                                           xsh=xshift,
                                           ysh=yshift,
                                           fit=None,
                                           xrms=xrms,
                                           yrms=yrms,
                                           verbose=False,
                                           force=True,
                                           sciext='SCI')

        # im = pyfits.open(file, mode='update')
        # wcs = pywcs.WCS(im[0].header)
        # wcs.rotateCD(-rot)
        # wcs.wcs.cd /= scale
        # #
        # im[0].header['CRPIX1'] += xshift
        # im[0].header['CRPIX2'] += yshift
        # #
        # for i in [0,1]:
        #     for j in [0,1]:
        #         im[0].header['CD%d_%d' %(i+1, j+1)] = wcs.wcs.cd[i,j]
        # #
        # im.flush()

    return xshift, yshift, rot, scale, xrms, yrms
예제 #5
0
def matchOctSept():
    global liststars, masteroctlines, masterseptlines
    septxlist, septylist, septmatchlinelist, octmatchlinelist, septcatlinelist, octcatlinelist, oct_total, octlineno, \
    septlineno, octxlist, octylist = [], [], [], [], [], [], [], [], [], [], []
    # create list of acceptable sources in september
    with open(septextracted[0], "r") as f:
        lines = f.readlines()
        RAs, Decs = [], []

        for x in lines:
            line = x.split(' ')
            if (not x.startswith("N")) and int(line[3]) == 0 \
                    and uppersept > float(line[1]) > lowersept and uppersept > float(line[2]) > lowersept:
                septxlist.append(line[1])
                septylist.append(line[2])
                septlineno.append('#%s' % line[0])
                RAs.append('#%s' % line[5])
                Decs.append('#%s' % line[6])

    with open((userdata + 'match1.xml'), 'w') as f:
        for y in range(len(septxlist)):
            f.write('circle(%s,%s,%s)' % (septxlist[y], septylist[y], 30) +
                    '\n')

    septxy = ((sept + 'xysept_full.txt'))
    ascii.write([septxlist, septylist, septlineno, RAs, Decs],
                septxy,
                names=('#x', 'y', 'line no.', 'RA', 'Dec'),
                overwrite=True)

    for num in range(len(octclean)):
        octfile = octclean[num]

        with open(octfile, "r") as f:
            lines = f.readlines()
            for x in lines:
                line = x.split(' ')
                if int(line[3]) == 0:
                    octxlist.append(line[1])
                    octylist.append(line[2])
                    octlineno.append('#%s' % line[0])

        octxy = oct + 'c%s_xyoct_full.txt' % (num + 1)
        ascii.write([octxlist, octylist, octlineno],
                    octxy,
                    names=('#x', 'y', 'line no.'),
                    overwrite=True)
        del octxlist[:], octylist[:], octlineno[:]
        str_out = 'c%s_oct_sept_match.txt' % (num + 1)
        refpnt = (reference + '%sref.txt' % (num + 1))

        iraf.xyxymatch(input=(sept + 'xysept_full.txt'),
                       reference=octxy,
                       output=str_out,
                       xmag=1.0,
                       ymag=1.0,
                       refpoints=refpnt,
                       matching="tolerance",
                       tolerance=3,
                       verbose="no")
        with open(str_out, "r") as f:
            lines = f.readlines()
            for x in lines:
                x = x.strip()
                if not x or x.startswith('#'):
                    continue
                septmatchlinelist.append(int(x.split()[5]) - 1)
                octmatchlinelist.append(int(x.split()[4]) - 1)

        if len(septmatchlinelist) != len(
                set(septmatchlinelist)) or len(octmatchlinelist) != len(
                    set(octmatchlinelist)):
            print "Error: tweak xyxymatch parameters so that a coordinate in one set of data isn't matched to " \
                  "multiple coordinates in the other"
            print num
            sys.exit()

        with open((sept + 'xysept_full.txt'), 'r') as fs:
            tempsept, tempoct = np.array(septmatchlinelist), np.array(
                octmatchlinelist)
            with open(octxy, 'r') as f:
                lines = fs.readlines()
                linesoct = f.readlines()
                i = 1
                for x in lines:
                    line = x.split('#')
                    if x.startswith("#"):
                        continue
                    elif i in septmatchlinelist:
                        septcatlinelist.append(int(line[1]))
                        masterseptlines[num].append(int(line[1]))
                        RA.append(float(line[2]))
                        Dec.append(float(line[3]))
                        p = linesoct[octmatchlinelist[np.where(
                            tempsept == i)[0][0]]].split('#')
                        octcatlinelist.append(int(p[1]))
                        masteroctlines[num].append(int(p[1]))
                    i += 1

        temptotal = []
        with open(octfile, 'r') as f:
            tempoct = np.array(octcatlinelist)
            lines = f.readlines()
            for x in lines:
                z = int(x.split(' ')[0])
                if x.startswith("#"):
                    continue
                elif z in octcatlinelist:
                    a = np.where(tempoct == z)[0][0]
                    temptotal.append('%s %s %s %s\n' %
                                     (x.rstrip('\n'), RA[a], Dec[a],
                                      (num + 1)))

        for item in range(len(temptotal)):
            if int(temptotal[item].split(' ')[0]) in liststars[num]:
                oct_total.append(temptotal[item])
        del septmatchlinelist[:], octmatchlinelist[:], septcatlinelist[:], octcatlinelist[:], RA[:], Dec[:], temptotal[:]

    with open('oct_total.txt', 'w') as f:
        for item in oct_total:
            f.write('%s' % item)
예제 #6
0
def stacking(cllist,zpofflist,ref,zprefoff=0.0,stackname='stack',shiftsize=400):

    """
    """

    #Reset the IRAF tasks used in this routine.
    iraf.unlearn('imcalc')
    iraf.unlearn('imcombine')
    iraf.unlearn('imreplace')
    iraf.unlearn('xyxymatch')
    iraf.unlearn('geomap')
    iraf.unlearn('geotran')
    iraf.unlearn('imcopy')

    #Find reference image in reference directory. Check to make
    #sure that it is actually the image and not the mask file!
    #Grab the mask for adding to the mask list now.
    (refimg,refmask,expmap)=classify(ref+'/tu*.fits')
    zpref=pf.open(refimg)[0].header['MAGZERO']
#    zprefoff=NewfirmZPoffset[ref.split('/')[-1]]
    zprefoff=float(zprefoff)

    #Get 2MASS PSC positions for reference cluster image.
    catalog=get2masspsc(refimg)
    foo=file_check(ref+'/2mass_ref_stars.cdt',delete=True)
    foo=open(ref+'/2mass_ref_stars.cdt','w')
    for y in catalog:
        data=y.split()
        foo.write(data[6]+'\t'+data[7]+'\n')
    foo.close()

    #Create lists for files to be input into the stacking routine.
    foo=file_check('matchlist',delete=True)
    foo=file_check('scalelist',delete=True)
    foo=file_check('shiftlist',delete=True)
    foo=file_check('masklist',delete=True)
    foo=file_check('shiftmask',delete=True)
    foo=file_check('expmaplist',delete=True)
    (matchlist,scalelist,shiftlist,masklist,
     shiftmask,finalmasks,stacklist,stackmask,
     finalmasks2,expmaplist,shiftexp,expmaplist2)=(open('matchlist','w'),open('scalelist','w'),
                                        open('shiftlist','w'),open('masklist','w'),
                                        open('shiftmask','w'),open('finalmasks','w'),
                                        open('stacklist','w'),open('stackmask','w'),
                                        open('finalmasks2','w'),open('expmaplist','w'),
                                        open('shiftexp','w'),open('expmaplist2','w'))
    (xsize,ysize)=(np.array([]),np.array([]))
    
    
    #Step through all of the input cluster directories.
    i=0
    for x in cllist:
        #Find the image, mask, and exposure map files. Get zeropoints and
        #scale image to the reference image.
        scaleimg=x+'/scaled_to_'+ref.split('/')[-1]+'.fits'
        foo=file_check(scaleimg,delete=True)
        (img,mask,expmap)=classify(x+'/tu*.fits')
        imgzp=pf.open(img)[0].header['MAGZERO']
        (xs,ys)=(pf.open(img)[0].header['NAXIS1'],pf.open(img)[0].header['NAXIS2'])
        (xsize,ysize)=(np.append(xsize,xs),np.append(ysize,ys))

        imgzpoff=float(zpofflist[i])
#        imgzpoff=NewfirmZPoffset[x.split('/')[-1]]
        scale=scalecounts(imgzp+imgzpoff,zpref+zprefoff)
        iraf.imcalc(img,scaleimg,'im1*'+str(scale))

        #Get X,Y pixel positions of 2MASS sources from the 2MASS PSC
        #in the image. Use these to compute shifts relative to the
        #reference image using IRAF task geomap.
        foo=file_check(x+'/2mass_ref_stars.cdt',delete=True)
        foo=open(x+'/2mass_ref_stars.cdt','w')
        catalog=get2masspsc(scaleimg)
        for y in catalog:
            data=y.split()
            foo.write(data[6]+'\t'+data[7]+'\n')
        foo.close()
    
        #Match the 2MASS PSC positions with stars in the reference
        #image using xyxymatch. The matched source list is then fed
        #into geomap to get the X and Y shifts.
        foo=file_check(x+'/2mass_matched.cdt',delete=True)
        iraf.xyxymatch(x+'/2mass_ref_stars.cdt',ref+'/2mass_ref_stars.cdt',
                       x+'/2mass_matched.cdt','200.0',verbose='no')

        #Append all of the names of the files for the input and output filename
        #lists to be passed to IRAF tasks further down the line.
        matchlist.write(x+'/2mass_matched.cdt\n')
        scalelist.write(scaleimg+'\n')
        foo=file_check(x+'/scaled_and_shifted.fits',delete=True)
        shiftlist.write(x+'/scaled_and_shifted.fits['+str(shiftsize)+':'+\
                 str(int(np.max(xsize))+shiftsize)+','+str(shiftsize)+':'+\
                 str(int(np.max(ysize))+shiftsize)+']\n')
        stacklist.write(x+'/scaled_and_shifted.fits\n')
        file_check(x+'/mask_tmp.fits',delete=True)
        file_check(x+'/expmap_tmp.fits',delete=True)
        iraf.imarith(mask+'[1]','*',1000.0,x+'/mask_tmp.fits',pixtype='real')
        iraf.imarith(expmap+'[1]','*',1.0,x+'/expmap_tmp.fits',pixtype='real')
        offset=2.558435
        file_check(x+'/mask_tmp2.fits',delete=True)
        iraf.imcalc(x+'/mask_tmp.fits',x+'/mask_tmp2.fits','im1+'+str(offset))
        os.remove(x+'/mask_tmp.fits')
        masklist.write(x+'/mask_tmp2.fits\n')
        file_check(x+'/mask_shift.fits',delete=True)
        shiftmask.write(x+'/mask_shift.fits['+str(shiftsize)+':'+\
                    str(int(np.max(xsize))+shiftsize)+','+str(shiftsize)+':'+\
                    str(int(np.max(ysize))+shiftsize)+']\n')
        stackmask.write(x+'/mask_shift.fits\n')
        finalmasks.write(x+'/mask_final.fits\n')
        finalmasks2.write(x+'/mask_final.fits[0]\n')
        expmaplist.write(x+'/expmap_tmp.fits[0]\n')
        shiftexp.write(x+'/expmap_shift.fits['+str(shiftsize)+':'+\
                    str(int(np.max(xsize))+shiftsize)+','+str(shiftsize)+':'+\
                    str(int(np.max(ysize))+shiftsize)+']\n')
        expmaplist2.write(x+'/expmap_shift.fits\n')
        i += 1

    #Close all of the input and output filename lists to be passed to IRAF tasks.
    matchlist.close()
    scalelist.close()
    stacklist.close()
    masklist.close()
    shiftmask.close()
    finalmasks.close()
    shiftlist.close()
    stackmask.close()
    finalmasks2.close()
    expmaplist.close()
    expmaplist2.close()
    shiftexp.close()

    #Get the shifts between all input files (including the reference) and the
    #reference image itself.
    foo=file_check('shift.db',delete=True)
    iraf.geomap('@matchlist','shift.db',1.0,np.max(xsize),
                1.0,np.max(ysize),fitgeometry='shift',interactive='no',
                maxiter=2,function='legendre',verbose='no')

    #Shift the input images (including the reference) and associated mask files
    #to a common pixel grid. Add some padding around the individual frames (-99
    #in the images, 1 in the bad pixel masks) to ensure that the images will
    #combine properly.
    (maxx,maxy)=(np.max(xsize)+shiftsize+100.0,np.max(ysize)+shiftsize+100.0)
    iraf.geotran('@scalelist','@shiftlist','shift.db','@matchlist',geometry='linear',
                 boundary='constant',nlines=maxy,ncols=maxx,constant=-99.0)

    iraf.geotran('@masklist','@shiftmask','shift.db','@matchlist',geometry='linear',
                 boundary='constant',nlines=maxy,ncols=maxx,constant=1000.0,
                 nxblock=10000,nyblock=10000)
    
    iraf.geotran('@expmaplist','@shiftexp','shift.db','@matchlist',geometry='linear',
                 boundary='constant',nlines=maxy,ncols=maxx,constant=0.)

    for x in cllist:
        file_check(x+'/mask_final.fits',delete=True)
        shutil.copy(x+'/mask_shift.fits',x+'/mask_final.fits')
        iraf.hedit(x+'/scaled_and_shifted.fits[0]','BPM',x+'/mask_final.fits[0]',
                   add='yes',update='yes',verify='no')
    iraf.imreplace('@finalmasks2',0,upper=offset)
    iraf.imreplace('@finalmasks2',1,lower=offset)

    file_check(stackname,delete=True)
    file_check(stackname[:-5]+'_mask.pl',delete=True)
    file_check(stackname[:-5]+'_expmap.fits',delete=True)
    iraf.imcombine('@stacklist',stackname,bpmasks=stackname[:-5]+'_bpm',
                   masktype='goodval',reject='none',mclip='yes',lthresh='INDEF',hthresh='INDEF',
                   hsigma=10.0,lsigma='INDEF',nrejmasks=stackname[:-5]+'_nrej',
                   sigmas=stackname[:-5]+'_sigma',grow=2.5,nkeep=1,blank=-99.0,gain=8.0,rdnoise=35.0)
    iraf.imcombine('@expmaplist2',stackname[:-5]+'_expmap.fits',combine='sum')
    hdu=pf.open(stackname,mode='update')
    hdu[0].header['BPM']=stackname.split('/')[-1][:-5]+'_mask.pl'
    hdu[0].header['MAGZERO']=zpref+zprefoff
    hdu.close()

	#Fix the WCS information in the stacked image.
    copyhead(stackname,refimg,offset=shiftsize)
    applywcs(stackname,stackname[:-5]+'_wcs.fits')

    trash=['matchlist','scalelist','shiftlist','masklist','shiftmask','finalmasks',
            'shift.db','stacklist','finalmasks2','stackmask','tmp_wcs.fits','expmaplist',
            'expmaplist2','shiftexp']
    for x in trash:
        os.remove(x)
예제 #7
0
def cat_im_match(xref, yref, xin, yin, septol, **kwargs):
    '''Written by Gregory Rudnick 9 January 2018

    PURPOSE:

    Take two lists of x and y coordinates in the same units and match
    them within some tolerance.

    Plot the differences in each coordinate.

    INPUT PARAMETERS:

    xref, yref: the reference coordinates in pixels.  Numpy arrays.

    xin, yin: the input coordinates in pixels.  If performing
    coordinate transforms, these would be the ones to be transformed.
    Numpy arrays

    septol: the maximum separation allowed for a match.  Units are
    pixels

    OPTIONAL KEYWORD PARAMETERS

    icfile: The filename with the input reference coordinates
    for xyxymatch.  These need to be created by hand from the images

    matchfile: a name of the file that will contain the reference and
    input coordinates.  Suitable for geomap input.  Default is 'xyxy_out.txt'

    OUTPUT

    arrays containing row-matched (x,y) coordinates of the reference and input
    coordinates that fall with septol

    '''

    # #loop through all coordiantes and find closest match.  This is an
    # #N^2 process.  I can make it faster later.
    # #initialize distance coordinate
    # dist = np.full(xref.size, 1.e6)
    # #initialize array with indices of closest match
    # imatch = np.zeros(xref.size, dtype=np.int8)
    # for iref,valref in enumerate(xref):
    #     for iin,valin in enumerate(xin):
    #         #print("hi",iref,iin,xref[iref],xin[iin],yref[iref],yin[iin])
    #         disttest = np.sqrt( (xref[iref] - xin[iin])**2 +(yref[iref] - yin[iin])**2)

    #         #find the closest reference point to each input point
    #         if disttest < dist[iref]:
    #             #print(disttest,iref,iin)
    #             dist[iref] = disttest
    #             imatch[iref] = iin

    # #select close matches, where I assume septol is in pixels, just like the input catalog
    # iclose = np.where(dist < septol)
    # #convert tuple to pure array
    # iclose=iclose[0]

    #generate input files for xyxymatch from reference coordinates
    xyxy_refin = 'xyxymatch_refcoords.txt'
    fo = open(xyxy_refin, "w")
    for i, val in enumerate(xref):
        #print(i,iclose[i])
        #print(raref[iclose[i]],decref[iclose[i]],rain[idx[iclose[i]]],decin[idx[iclose[i]]])
        fo.write('{} {}\n'.format(xref[i], yref[i]))
    fo.close()

    xyxy_inin = 'xyxymatch_incoords.txt'
    fo = open(xyxy_inin, "w")
    for i, val in enumerate(xin):
        fo.write('{} {}\n'.format(xin[i], yin[i]))
    fo.close()

    #set xyxymatch output name if keyword is given
    xyxy_out = 'xyxy_match.txt'
    #remove geotran output file if it already exists
    if os.path.isfile(xyxy_out) is True:
        cmdstr = 'rm ' + xyxy_out
        os.system(cmdstr)

    #run xyxymatch and include a set of reference points if given as input
    if 'icfile' in kwargs.keys():
        iraf.xyxymatch(xyxy_inin, xyxy_refin, xyxy_out, septol, refpoints=kwargs['icfile'], \
                       xcolumn=1,ycolumn=2,xrcolumn=1,yrcolumn=2,matching="tolerance")
    else:
        iraf.xyxymatch(xyxy_inin, xyxy_refin, xyxy_out, septol, refpoints="", \
                       xcolumn=1,ycolumn=2,xrcolumn=1,yrcolumn=2,matching="tolerance")

    #read in xyxymatch output to get coordinate limits and to return
    #ordered matched coordinates
    xyxy_cat = ascii.read(xyxy_out)
    xref_m = np.array(xyxy_cat['col1'])
    yref_m = np.array(xyxy_cat['col2'])
    xin_m = np.array(xyxy_cat['col3'])
    yin_m = np.array(xyxy_cat['col4'])

    #write files only if "matchfile" keyword is set
    #this reformat of the xyxymatch code is just so that my other routines work
    keys = sorted(kwargs.keys())
    for kw in keys:
        if kw == 'matchfile':
            #print(kwargs[kw])
            #open file for writing and write a header
            fo = open(kwargs[kw], "w")
            fo.write("# xref yref xin yin\n")
            for i, val in enumerate(xref_m):
                #print(i,iclose[i])
                #print(raref[iclose[i]],decref[iclose[i]],rain[idx[iclose[i]]],decin[idx[iclose[i]]])
                fo.write('{} {} {} {}\n'.format(xref_m[i], yref_m[i], xin_m[i],
                                                yin_m[i]))
            fo.close()

    #store the limits of the coordinates
    lims = {
        'xmax': np.amax(xref_m),
        'xmin': np.amin(xref_m),
        'ymax': np.amax(yref_m),
        'ymin': np.amin(yref_m)
    }

    #return all matches within the tolerance
    return xref_m, yref_m, xin_m, yin_m, lims
예제 #8
0
def align_direct_to_reference(verbose=True, n_iter=20, drizzled_image=True):
	"""
	Use iraf software geomap to get shift solutions between images.

	n_iter = number of times to iterate over the alignment routines
	drizzled_image = boolean to distinguish between a drizzled image used for alignment,
	                 in which case the shifts must be transferred back to oiginal flt.
	"""

	### get the root name:
	root = wfc3_grism.options['ROOT_DIRECT']

	### get the alignment image which has been produced
	### with run_sregister_to_cutout_CANDELS_region()
	align_image = '%s_align_reference.fits' %(root)

	### now run SExtractor on the direct and refereance
	### images to build up 2 catalogs:
	se = wfc3_grism.sex.SExtractor()
	se.aXeParams()
	se.copyConvFile()
	se.overwrite = True
	se.options['CHECKIMAGE_TYPE'] = 'NONE'
	se.options['FILTER']    = 'Y'
	se.options['DETECT_THRESH']    = '%.1f' % wfc3_grism.options['ALIGN_DETECT_THRESH'] 
	se.options['ANALYSIS_THRESH']  = '3' 
	se.options['MAG_ZEROPOINT'] = '%.2f' % wfc3_grism.options['MAG_ZEROPOINT']
	se.options['DETECT_MINAREA'] = '%.1f' % wfc3_grism.options['ALIGN_DETECT_MINAREA'] 

	### generate the direct image catalog:
	se.options['CATALOG_NAME']    = 'direct.cat'
	iraf.imcopy('%s_drz.fits[SCI]' %(root), "SCI.fits", verbose=False)

	## if not using drizzled image for alignment done't include
	### a weight image:
	if drizzled_image:
		se.options['WEIGHT_TYPE']     = 'MAP_WEIGHT'
		se.options['WEIGHT_IMAGE']    = 'WHT.fits'
		iraf.imcopy('%s_drz.fits[WHT]' %(root), "WHT.fits", verbose=False)
	else:
		se.options['WEIGHT_TYPE']     = 'NONE'
		se.options['WEIGHT_IMAGE']    = 'WHT.fits'

	status = se.sextractImage('SCI.fits')

	### generate the alignment image catalog:
	se.options['CATALOG_NAME']    = 'align.cat'
	se.options['WEIGHT_TYPE']     = 'NONE'
	se.options['WEIGHT_IMAGE']    = 'WHT.fits'
	status = se.sextractImage(align_image)

	### Read the catalogs
	direct_cat = wfc3_grism.sex.mySexCat('direct.cat')
	align_cat = wfc3_grism.sex.mySexCat('align.cat')

	### initialize x,y shift parameters so can be 
	### updated with each iteration, the x,y shifts 
	### will converge twoard an optimal value over the
	### iterations:
	xshift = 0
	yshift = 0
	rot = 0
	scale = 1.

	### empty line in the output to make things clearer:
	print ""

	### now loop through the process until xrms and yrms both < 0.5
	### or run out of number of iterations:
	xrms, yrms = 100, 100
	toler = wfc3_grism.options['ALIGN_TOLERANCE']
	iteration = 0
	max_iter = wfc3_grism.options['ALIGN_ITERATIONS']
	while ((xrms > 0.1) | (yrms > 0.1)) & (iteration <= max_iter):

		print "Running matching algorithm on iteration #%d" %(iteration)

		### Get x,y coordinates of detected objects direct image
		fp = open('direct.xy','w')
		for i in range(len(direct_cat.X_IMAGE)):
			fp.write('%-15s%-15s\n' %(direct_cat.X_IMAGE[i],direct_cat.Y_IMAGE[i]))
		fp.close()

		### Get x,y coordinates of detected objects alignment image
		fp = open('align.xy','w')
		for i in range(len(align_cat.X_IMAGE)):
			fp.write('%-15s%-15s\n' %(np.float(align_cat.X_IMAGE[i])+xshift, np.float(align_cat.Y_IMAGE[i])+yshift))
		fp.close()

		### iraf flpr()
		wfc3_grism.utils.iraf_flpr()

		### remove previous solution:
		if iteration > 0:
			os.remove('align.match')

		### get the alignment catalog:
		status = iraf.xyxymatch(input="direct.xy", 
								reference="align.xy",
								output="align.match",
								tolerance=2**toler, 
								separation=0, 
								verbose=True, 
								Stdout=1)

		### iraf flpr()
		wfc3_grism.utils.iraf_flpr()

		### now get shifts with geomap:
		if iteration > 0:
			os.remove('align.map')

		iraf.geomap(input="align.match", 
					database="align.map",
					fitgeometry="shift", 
					interactive=False, 
					xmin=iraf.INDEF, 
					xmax=iraf.INDEF, 
					ymin=iraf.INDEF, 
					ymax=iraf.INDEF,
					maxiter = 10, 
					reject = 2.0, 
					Stdout=1)

		### get the output from geomap:
		fp = open("align.map", "r")
		for line in fp.readlines():
			spl = line.split()
			if spl[0].startswith('xshift'):
				xshift += float(spl[1])    
			if spl[0].startswith('yshift'):
				yshift += float(spl[1])    
			if spl[0].startswith('xrotation'):
				rot = float(spl[1])    
			if spl[0].startswith('xmag'):
				scale = float(spl[1])    
			if spl[0].startswith('xrms'):
				xrms = float(spl[1])    
			if spl[0].startswith('yrms'):
				yrms = float(spl[1])    
		fp.close()

		### update iteration counter:
		iteration += 1
		toler += 1

		print 'Shift iteration #%d, xshift=%f, yshift=%f, rot=%f, scl=%f (rms: %5.2f,%5.2f)' %(iteration, xshift, yshift, rot, scale, xrms, yrms)

	### copy the final align.map for posterity:
	shutil.copy('align.map', '%s_align.map' %(root))

	## cleanup from the alignment process:
	remvfiles = ['SCI.fits','WHT.fits','align.cat',
				'align.map','align.match','align.reg','align.xy',
				'direct.cat','direct.reg','direct.xy',
				'drz_sci.fits','drz_wht.fits','bg.fits', 'imxymatch.1', 'sex_stderr',
				'wfc3_grism_auto.sex', 'wfc3_grism_auto.param', 'default.nnw', 'default.conv']

	for file in remvfiles:
		try:
			os.remove(file)
		except:
			pass

	if drizzled_image:
		#### shifts measured in drz frame.  Translate to the flt frame:
		drz = fits.open('%s_drz.fits' %(root))

		#### Get reference angle from first image in the ASN file:
		asn = wfc3_grism.utils.ASNFile('%s_asn.fits' %(root))
		alpha = (180. - fits.getheader(asn.exposures[0]+'_flt.fits', 1)['PA_APER']) / 360. * 2 * np.pi

		### Get the drizzle scale from the MultiDrizzle '.run' file:
		for line in open('%s.run' %(root),'r'):
			if line.startswith('drizzle.scale'):
				drizzle_scale = line.split()[2]

		print drizzle_scale

		### get the equivalent shifts in the FLT frames:
		xsh = (xshift*np.cos(alpha) - yshift*np.sin(alpha))*np.float(drizzle_scale)
		ysh = (xshift*np.sin(alpha) + yshift*np.cos(alpha))*np.float(drizzle_scale)

		print 'Final shift:', xsh, ysh, drz[1].header['PA_APER']
	else:
		xsh = xshift
		ysh = yshift

	fp = open('%s_align.info' %(root),'w')
	fp.write('%s %8.3f %8.3f %8.3f\n' %(align_image, xsh, ysh, rot)) 
	fp.close()

	#### Read the shiftfile
	if drizzled_image:

		shiftF = ShiftFile('%s_initial_shifts.txt' %(root))

		shiftF.xshift = list(np.array(shiftF.xshift)-xsh)
		shiftF.yshift = list(np.array(shiftF.yshift)-ysh)
		shiftF.rotate = list((np.array(shiftF.rotate)+rot) % 360)
		shiftF.scale = list(np.array(shiftF.scale)*scale)

		shiftF.write('%s_final_shifts.txt' %(root))

	else:
		### use the default shift file in wfc3_grism data folder:
		shiftF = ShiftFile('/disk1/fc/FIGS/wfc3_grism/data/default_shift_file.txt')

		### add the reference image as needed by multidrizzle:
		shiftF.headerlines[1] = '# refimage: %s \n' %(align_image)

		#### Apply the alignment shifts to the shiftfile
		shiftF.xshift = [np.array(xsh)]
		shiftF.yshift = [np.array(ysh)]
		shiftF.rotate = [np.array(rot) % 360]
		shiftF.scale = [np.array(scale)]

		shiftF.write('%s_final_shifts.txt' %(root))
예제 #9
0
def align_to_reference(ROOT_DIRECT,
                       ALIGN_IMAGE,
                       fitgeometry="shift",
                       clean=True,
                       verbose=False,
                       ALIGN_EXTENSION=0,
                       toler=3,
                       skip_swarp=False,
                       align_sdss_ds9=False,
                       catalog=None):
    """
xshift, yshift, rot, scale, xrms, yrms = align_to_reference()
    """
    import os
    import glob
    import shutil

    from pyraf import iraf
    from iraf import stsdas, dither

    import threedhst
    from threedhst import catIO

    no = iraf.no
    yes = iraf.yes
    INDEF = iraf.INDEF

    #### Clean slate
    rmfiles = [
        'SCI.fits', 'WHT.fits', 'align.cat', 'direct.cat'
        'align.map', 'align.match', 'align.reg', 'align.xy', 'direct.reg',
        'direct.xy', 'ds9_align.tsv'
    ]

    for file in rmfiles:
        try:
            os.remove(file)
        except:
            pass

    if catalog is not None:
        align_sdss_ds9 = True

    #### Get only images that overlap from the ALIGN_IMAGE list
    if not align_sdss_ds9:
        align_img_list = find_align_images_that_overlap(
            ROOT_DIRECT + '_drz.fits',
            ALIGN_IMAGE,
            ALIGN_EXTENSION=ALIGN_EXTENSION)
        if not align_img_list:
            print 'threedhst.shifts.align_to_reference: no alignment images overlap.'
            return 0, 0

    #### Use swarp to combine the alignment images to the same image
    #### dimensions as the direct mosaic
    if (not skip_swarp) & (not align_sdss_ds9):
        try:
            os.remove(ROOT_DIRECT + '_align.fits')
        except:
            pass
        matchImagePixels(input=align_img_list,
                         matchImage=ROOT_DIRECT + '_drz.fits',
                         output=ROOT_DIRECT + '_align.fits',
                         match_extension=1,
                         input_extension=ALIGN_EXTENSION)

    #### Run SExtractor on the direct image, with the WHT
    #### extension as a weight image
    se = threedhst.sex.SExtractor()
    se.aXeParams()
    se.copyConvFile()
    se.overwrite = True
    se.options['CHECKIMAGE_TYPE'] = 'NONE'
    se.options['WEIGHT_TYPE'] = 'MAP_WEIGHT'
    se.options['WEIGHT_IMAGE'] = 'WHT.fits'
    se.options['FILTER'] = 'Y'
    ## Detect thresholds (default = 1.5)
    THRESH = 10
    if align_sdss_ds9:
        if 'Vizier' not in REFERENCE_CATALOG:
            THRESH = 20

    se.options['DETECT_THRESH'] = '%d' % (THRESH)
    se.options['ANALYSIS_THRESH'] = '%d' % (THRESH)
    se.options['MAG_ZEROPOINT'] = str(threedhst.options['MAG_ZEROPOINT'])

    #### Run SExtractor on direct and alignment images
    ## direct image
    se.options['CATALOG_NAME'] = 'direct.cat'
    iraf.imcopy(ROOT_DIRECT + '_drz.fits[1]', "SCI.fits")
    iraf.imcopy(ROOT_DIRECT + '_drz.fits[2]', "WHT.fits")
    status = se.sextractImage('SCI.fits')

    ## Read the catalog
    directCat = threedhst.sex.mySexCat('direct.cat')

    if align_sdss_ds9:
        ### Use ds9 SDSS catalog to refine alignment
        import threedhst.dq
        import pywcs
        import threedhst.catIO as catIO

        wcs = pywcs.WCS(pyfits.getheader('SCI.fits', 0))
        #wcs = pywcs.WCS(pyfits.getheader('Q0821+3107-F140W_drz.fits', 1))

        if 'Vizier' in REFERENCE_CATALOG:
            #### Use (unstable) astroquery Vizier search
            #### CFHTLS-Deep: 'Vizier.II/317'
            VIZIER_CAT = REFERENCE_CATALOG.split('Vizier.')[1]
            print 'Align to Vizier catalog: http://vizier.u-strasbg.fr/viz-bin/VizieR?-source=%s' % (
                VIZIER_CAT)

            import astroquery
            if astroquery.__version__ < '0.0.dev1078':
                from astroquery import vizier

                query = {}
                query["-source"] = VIZIER_CAT
                #query["-out"] = ["_r", "CFHTLS", "rmag"]
                query["-out"] = ["_RAJ2000", "_DEJ2000"]  ### Just RA/Dec.

                #### Center position and query radius
                r0, d0 = wcs.wcs_pix2sky([[wcs.naxis1 / 2., wcs.naxis2 / 2.]],
                                         1)[0]
                rll, dll = wcs.wcs_pix2sky([[0, 0]], 1)[0]
                corner_radius = np.sqrt(
                    (r0 - rll)**2 * np.cos(d0 / 360. * 2 * np.pi)**2 +
                    (d0 - dll)**2) * 60. * 1.5
                h = query["-c"] = "%.6f %.6f" % (r0, d0)
                query["-c.rm"] = "%.3f" % (corner_radius
                                           )  ### xxx check image size

                #### Run the query
                vt = vizier.vizquery(query)
            else:
                #### Newer astroquery
                from astroquery.vizier import Vizier
                import astropy.coordinates as coord
                import astropy.units as u

                Vizier.ROW_LIMIT = -1

                r0, d0 = wcs.wcs_pix2sky([[wcs.naxis1 / 2., wcs.naxis2 / 2.]],
                                         1)[0]
                rll, dll = wcs.wcs_pix2sky([[0, 0]], 1)[0]
                corner_radius = np.sqrt(
                    (r0 - rll)**2 * np.cos(d0 / 360. * 2 * np.pi)**2 +
                    (d0 - dll)**2) * 60. * 1.5
                #
                c = coord.ICRSCoordinates(ra=r0, dec=d0, unit=(u.deg, u.deg))
                #### something with astropy.coordinates
                # c.icrs.ra.degree = c.icrs.ra.degrees
                # c.icrs.dec.degree = c.icrs.dec.degrees
                #
                vt = Vizier.query_region(c,
                                         width=u.Quantity(
                                             corner_radius, u.arcminute),
                                         catalog=[VIZIER_CAT])[0]

            #### Make a region file
            ra_list, dec_list = vt['RAJ2000'], vt['DEJ2000']
            print 'Vizier, found %d objects.' % (len(ra_list))
            fp = open('%s.vizier.reg' % (ROOT_DIRECT), 'w')
            fp.write('# %s, r=%.1f\'\nfk5\n' % (VIZIER_CAT, corner_radius))
            for ra, dec in zip(ra_list, dec_list):
                fp.write('circle(%.6f, %.6f, 0.5")\n' % (ra, dec))
            #
            fp.close()
        else:
            #### Use DS9 catalog
            ds9 = threedhst.dq.myDS9()
            ds9.set('file SCI.fits')
            #ds9.set('file Q0821+3107-F140W_drz.fits')
            ds9.set('catalog %s' % (REFERENCE_CATALOG))
            ### Can't find XPA access point for "copy to regions"
            ds9.set('catalog export tsv ds9_align.tsv')
            lines = open('ds9_align.tsv').readlines()
            ra_list, dec_list = [], []
            for line in lines[1:]:
                spl = line.split()
                ra, dec = float(spl[0]), float(spl[1])
                ra_list.append(ra)
                dec_list.append(dec)
            #
            del (ds9)

        x_image, y_image = [], []
        for ra, dec in zip(ra_list, dec_list):
            x, y = wcs.wcs_sky2pix([[ra, dec]], 1)[0]
            x_image.append(x)
            y_image.append(y)

        alignCat = catIO.EmptyCat()
        alignCat['X_IMAGE'] = np.array(x_image)
        alignCat['Y_IMAGE'] = np.array(y_image)

    else:
        ## alignment image
        se.options['CATALOG_NAME'] = 'align.cat'
        status = se.sextractImage(ROOT_DIRECT + '_align.fits')
        alignCat = threedhst.sex.mySexCat('align.cat')

    xshift = 0
    yshift = 0
    rot = 0
    scale = 1.

    xrms = 2
    yrms = 2

    NITER = 5
    IT = 0
    while (IT < NITER):
        IT = IT + 1

        #### Get x,y coordinates of detected objects
        ## direct image
        fp = open('direct.xy', 'w')
        for i in range(len(directCat.X_IMAGE)):
            fp.write('%s  %s\n' % (directCat.X_IMAGE[i], directCat.Y_IMAGE[i]))
        fp.close()

        ## alignment image
        fp = open('align.xy', 'w')
        for i in range(len(alignCat.X_IMAGE)):
            fp.write('%s  %s\n' % (np.float(alignCat.X_IMAGE[i]) + xshift,
                                   np.float(alignCat.Y_IMAGE[i]) + yshift))
        fp.close()

        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        #### iraf.xyxymatch to find matches between the two catalogs
        pow = toler * 1.
        try:
            os.remove('align.match')
        except:
            pass

        status1 = iraf.xyxymatch(input="direct.xy",
                                 reference="align.xy",
                                 output="align.match",
                                 tolerance=2**pow,
                                 separation=0,
                                 verbose=yes,
                                 Stdout=1)

        nmatch = 0
        while status1[-1].startswith('0') | (nmatch < 10):
            pow += 1
            os.remove('align.match')
            status1 = iraf.xyxymatch(input="direct.xy",
                                     reference="align.xy",
                                     output="align.match",
                                     tolerance=2**pow,
                                     separation=0,
                                     verbose=yes,
                                     Stdout=1)
            #
            nmatch = 0
            for line in open('align.match').xreadlines():
                nmatch += 1

        if verbose:
            for line in status1:
                print line

        #### Compute shifts with iraf.geomap
        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        try:
            os.remove("align.map")
        except:
            pass

        status2 = iraf.geomap(input="align.match",
                              database="align.map",
                              fitgeometry=fitgeometry,
                              interactive=no,
                              xmin=INDEF,
                              xmax=INDEF,
                              ymin=INDEF,
                              ymax=INDEF,
                              maxiter=10,
                              reject=2.0,
                              Stdout=1)
        if verbose:
            for line in status2:
                print line

        #fp = open(root+'.iraf.log','a')
        #fp.writelines(status1)
        #fp.writelines(status2)
        #fp.close()

        #### Parse geomap.output
        fp = open("align.map", "r")
        for line in fp.readlines():
            spl = line.split()
            if spl[0].startswith('xshift'):
                xshift += float(spl[1])
            if spl[0].startswith('yshift'):
                yshift += float(spl[1])
            if spl[0].startswith('xrotation'):
                rot = float(spl[1])
            if spl[0].startswith('xmag'):
                scale = float(spl[1])
            if spl[0].startswith('xrms'):
                xrms = float(spl[1])
            if spl[0].startswith('yrms'):
                yrms = float(spl[1])

        fp.close()

        #os.system('wc align.match')
        print 'Shift iteration #%d, xshift=%f, yshift=%f, rot=%f, scl=%f (rms: %5.2f,%5.2f)' % (
            IT, xshift, yshift, rot, scale, xrms, yrms)

    im = pyfits.open('SCI.fits')

    shutil.copy('align.map', ROOT_DIRECT + '_align.map')
    shutil.copy('align.match', ROOT_DIRECT + '_align.match')

    #### Cleanup
    if clean:
        rmfiles = [
            'SCI.fits', 'WHT.fits', 'align.cat', 'align.map', 'align.match',
            'align.reg', 'align.xy', 'direct.cat', 'direct.reg', 'direct.xy',
            'drz_sci.fits', 'drz_wht.fits', 'bg.fits'
        ]

        for file in rmfiles:
            try:
                os.remove(file)
            except:
                pass

    return xshift, yshift, rot, scale, xrms, yrms
예제 #10
0
def plot_shifts(ROOT_DIRECT,
                ALIGN_IMAGE,
                clean=True,
                verbose=True,
                ALIGN_EXTENSION=0,
                toler=3,
                skip_swarp=False,
                threshold=7,
                force=False,
                drz=True,
                WEIGHT_IMAGE=None):
    """
    Run SExtractor on two images and match the objects to plot the shifts between them.
    
    ALIGN_IMAGE is a string that may contain wildcards, and the function will use 
    `align_img_list` to find ALIGN_IMAGEs
    """
    import glob

    from pyraf import iraf
    from iraf import stsdas, dither

    no = iraf.no
    yes = iraf.yes
    INDEF = iraf.INDEF

    if os.path.exists(ROOT_DIRECT + '_align.fits') & (not force):
        if verbose:
            print 'Image %s_align.fits exists.  Skipping SWarp.' % (
                ROOT_DIRECT)
        skip_swarp = True

    if not skip_swarp:
        if drz:
            align_img_list = find_align_images_that_overlap(
                ROOT_DIRECT + '_drz.fits',
                ALIGN_IMAGE,
                ALIGN_EXTENSION=ALIGN_EXTENSION)
        else:
            align_img_list = glob.glob(ALIGN_IMAGE)

        if not align_img_list:
            print 'threedhst.shifts.align_to_reference: no alignment images overlap.'
            return 0, 0
        #
        try:
            os.remove(ROOT_DIRECT + '_align.fits')
        except:
            pass

        if drz:
            matchImagePixels(input=align_img_list,
                             matchImage=ROOT_DIRECT + '_drz.fits',
                             output=ROOT_DIRECT + '_align.fits',
                             match_extension=1,
                             input_extension=ALIGN_EXTENSION)
            ALIGN_FITS = ROOT_DIRECT + '_align.fits'
        else:
            ALIGN_FITS = os.path.basename(
                ROOT_DIRECT.split('.fits')[0]) + '_align.fits'
            matchImagePixels(input=align_img_list,
                             matchImage=ROOT_DIRECT,
                             output=ALIGN_FITS,
                             match_extension=0,
                             input_extension=ALIGN_EXTENSION)

    se = threedhst.sex.SExtractor()
    se.aXeParams()
    se.copyConvFile()
    se.overwrite = True
    se.options['CHECKIMAGE_TYPE'] = 'NONE'
    se.options['WEIGHT_TYPE'] = 'MAP_WEIGHT'

    if drz:
        se.options['WEIGHT_IMAGE'] = ROOT_DIRECT + '_drz.fits[1]'
    else:
        if WEIGHT_IMAGE:
            se.options['WEIGHT_IMAGE'] = WEIGHT_IMAGE
        else:
            se.options['WEIGHT_TYPE'] = 'NONE'
            se.options['WEIGHT_IMAGE'] = 'NONE'

    se.options['FILTER'] = 'Y'
    ## Detect thresholds (default = 1.5)
    se.options['DETECT_THRESH'] = '%f' % (threshold)
    se.options['ANALYSIS_THRESH'] = '%f' % (threshold)
    se.options['MAG_ZEROPOINT'] = str(threedhst.options['MAG_ZEROPOINT'])

    #### Run SExtractor on direct and alignment images
    ## direct image
    se.options['CATALOG_NAME'] = 'direct.cat'
    if drz:
        status = se.sextractImage(ROOT_DIRECT + '_drz.fits[0]')
        INPUT_IMAGE = ROOT_DIRECT + '_drz.fits'
    else:
        status = se.sextractImage(ROOT_DIRECT)
        INPUT_IMAGE = ROOT_DIRECT

    ## alignment image
    se.options['CATALOG_NAME'] = 'align.cat'
    se.options['WEIGHT_TYPE'] = 'NONE'
    status = se.sextractImage(ALIGN_FITS)

    ## Read the catalogs
    directCat = threedhst.sex.mySexCat('direct.cat')
    alignCat = threedhst.sex.mySexCat('align.cat')

    xshift = 0
    yshift = 0
    rot = 0
    scale = 1.

    xrms = 2
    yrms = 2

    NITER = 5
    IT = 0
    while (IT < NITER):
        IT = IT + 1

        #### Get x,y coordinates of detected objects
        ## direct image
        fp = open('direct.xy', 'w')
        for i in range(len(directCat.X_IMAGE)):
            fp.write('%s  %s\n' % (directCat.X_IMAGE[i], directCat.Y_IMAGE[i]))
        fp.close()

        ## alignment image
        fp = open('align.xy', 'w')
        for i in range(len(alignCat.X_IMAGE)):
            fp.write('%s  %s\n' % (np.float(alignCat.X_IMAGE[i]) + xshift,
                                   np.float(alignCat.Y_IMAGE[i]) + yshift))
        fp.close()

        iraf.flpr()
        iraf.flpr()
        iraf.flpr()

        #### iraf.xyxymatch to find matches between the two catalogs
        pow = toler * 1.
        try:
            os.remove('align.match')
        except:
            pass

        status1 = iraf.xyxymatch(input="direct.xy",
                                 reference="align.xy",
                                 output="align.match",
                                 tolerance=2**pow,
                                 separation=0,
                                 verbose=yes,
                                 Stdout=1)

        while status1[-1].startswith('0'):
            pow += 1
            os.remove('align.match')
            status1 = iraf.xyxymatch(input="direct.xy",
                                     reference="align.xy",
                                     output="align.match",
                                     tolerance=2**pow,
                                     separation=0,
                                     verbose=yes,
                                     Stdout=1)

    #### Images are aligned, plot the offsets

    dx, dy, ax, ay, di, ai = np.loadtxt('align.match', unpack=True)

    ddx, ddy = dx - ax, dy - ay
    keep = (np.abs(ddx) < 15) & (np.abs(ddy) < 15)
    for i in range(5):
        sx, sy = threedhst.utils.biweight(
            ddx[keep], both=True), threedhst.utils.biweight(ddy[keep],
                                                            both=True)
        keep = keep & (np.abs(ddx - sx[0]) < 5 * sx[1]) & (np.abs(ddy - sy[0])
                                                           < 5 * sy[1])

    if USE_PLOT_GUI:
        fig = plt.figure(figsize=[8, 4], dpi=100)
    else:
        fig = Figure(figsize=[8, 4], dpi=100)

    fig.subplots_adjust(wspace=0.28,
                        hspace=0.0,
                        left=0.08,
                        bottom=0.14,
                        right=0.98,
                        top=0.98)

    ax = fig.add_subplot(121)

    ax.plot(ddx,
            ddy,
            marker='o',
            linestyle='None',
            color='black',
            alpha=0.4,
            ms=2,
            zorder=-1)
    ax.errorbar(sx[0],
                sy[0],
                sx[1],
                sy[1],
                marker='o',
                ms=0.1,
                color='white',
                linewidth=3,
                zorder=100)
    ax.errorbar(sx[0],
                sy[0],
                sx[1],
                sy[1],
                marker='o',
                ms=0.1,
                color='red',
                linewidth=2,
                zorder=500)

    ax.grid(alpha=0.5)
    dwin = 5 * np.max([sx[1], sy[1]])
    ax.set_xlim(sx[0] - dwin, sx[0] + dwin)
    ax.set_ylim(sy[0] - dwin, sy[0] + dwin)
    ax.set_xlabel(r'$\Delta x$ [pix]')
    ax.set_ylabel(r'$\Delta y$ [pix]')
    ax.text(0.5,
            0.95,
            os.path.basename(INPUT_IMAGE),
            fontsize=9,
            horizontalalignment='center',
            transform=ax.transAxes)
    ax.text(0.5,
            0.9,
            os.path.basename(ALIGN_IMAGE),
            fontsize=9,
            horizontalalignment='center',
            transform=ax.transAxes)

    ax.text(0.5,
            0.1,
            r'$\Delta x, \Delta y = %.2f \pm %.2f, %.2f \pm %.2f)$' %
            (sx[0], sx[1], sy[0], sy[1]),
            fontsize=11,
            horizontalalignment='center',
            transform=ax.transAxes)

    ax = fig.add_subplot(122)

    ax.plot(dx[keep],
            dy[keep],
            marker='o',
            ms=1,
            linestyle='None',
            color='black',
            alpha=0.1)
    ax.quiver(dx[keep],
              dy[keep],
              ddx[keep],
              ddy[keep],
              alpha=0.5,
              angles='xy',
              headlength=1,
              headwidth=1,
              scale=30. / (dx.max() - dx.min()),
              units='x',
              minlength=1)
    aa = np.array([1, 1])
    ax.quiver(dx[keep].mean() * aa,
              dy[keep].max() * 0.95 * aa,
              1 * aa,
              0 * aa,
              alpha=0.9,
              angles='xy',
              headlength=0,
              headwidth=1,
              scale=30. / (dx.max() - dx.min()),
              units='x',
              color='red')

    ax.set_xlabel(r'$x$ [pix]')
    ax.set_ylabel(r'$y$ [pix]')

    if USE_PLOT_GUI:
        fig.savefig(os.path.basename(ROOT_DIRECT.split('.fits')[0]) +
                    '_align.pdf',
                    dpi=100,
                    transparent=False)
    else:
        canvas = FigureCanvasAgg(fig)
        canvas.print_figure(os.path.basename(ROOT_DIRECT.split('.fits')[0]) +
                            '_align.pdf',
                            dpi=100,
                            transparent=False)

    if clean:
        rmfiles = [
            'SCI.fits', 'WHT.fits', 'align.cat', 'align.map', 'align.match',
            'align.reg', 'align.xy', 'direct.cat', 'direct.reg', 'direct.xy',
            'drz_sci.fits', 'drz_wht.fits', 'bg.fits'
        ]

        for file in rmfiles:
            try:
                os.remove(file)
            except:
                pass
예제 #11
0
파일: align.py 프로젝트: gbrammer/pabeta
def get_align_to_subaru(sci='M0416_Ks_c1_mp_avg.fits', wht='M0416_Ks_c1_mp_exp.fits', field='', clean=True, toler=3, verbose=False, fitgeometry='shift', shift_max=20, rms_max=1.1, rot_max=2, rot_only=True, THRESH=2, align_data=None):
    """
    Align HAWK-I images to the FF Subaru astrometric reference catalogs
    """
    
    #sci='M0416_Ks_c1_mp_avg.fits'; wht='M0416_Ks_c1_mp_exp.fits'
    
    ### Make object catalog
    se = threedhst.sex.SExtractor()
    se.aXeParams()
    se.copyConvFile()
    se.overwrite = True
    se.options['CHECKIMAGE_TYPE'] = 'NONE'
    if wht is None:
        se.options['WEIGHT_TYPE']     = 'NONE'
    else:
        se.options['WEIGHT_TYPE']     = 'MAP_WEIGHT'
        se.options['WEIGHT_IMAGE']    = wht
    
    se.options['FILTER']    = 'Y'
               
    se.options['DETECT_THRESH']    = '%d' %(THRESH)
    se.options['ANALYSIS_THRESH']  = '%d' %(THRESH)
    se.options['MAG_ZEROPOINT'] = '26.0'

    #### Run SExtractor on direct and alignment images
    ## direct image
    se.options['CATALOG_NAME']    = 'direct.cat'
    status = se.sextractImage(sci)
    threedhst.sex.sexcatRegions('direct.cat', 'direct.reg', format=2)
    
    directCat = threedhst.sex.mySexCat('direct.cat')
    
    #### Get the X/Y coords of the reference catalog    
    #head = pyfits.getheader(sci, 0)
    #wcs = pywcs.WCS(head)
    if 'M0416' in sci:
        ra_list, dec_list, mag = np.loadtxt(os.getenv('HAWKI')+'/FrontierFields/HST/hlsp_frontier_subaru_suprimecam_macs0416-astrom_R_v1_cat.txt', unpack=True)
        if ('c4' in sci):
            ra_list, dec_list, mag = np.loadtxt(os.getenv('HAWKI')+'/FrontierFields/HST/M0416/macs0416_f814w_radec.cat', unpack=True)
    #
    if 'M0717' in sci:
        ra_list, dec_list, mag = np.loadtxt('subaru.radec', unpack=True)

    if ('M1149' in sci) | (field == 'M1149'):
        ra_list, dec_list, mag = np.loadtxt('/Users/brammer/Research/VLT/HAWKI/MACS1149/hlsp_frontier_subaru_suprimecam_macs1149-astrom_R_v1_cat.txt', unpack=True)
            
    if 'A2744' in sci:
        ra_list, dec_list, mag = np.loadtxt(os.getenv('HAWKI')+'/FrontierFields/HST/hlsp_frontier_subaru_suprimecam_abell2744-astrom_i_v1_cat.txt', unpack=True)
        if ('c1' in sci) | ('c4' in sci):
            ra_list, dec_list, mag = np.loadtxt(os.getenv('HAWKI')+'/FrontierFields/HST/abell2744_f814w_radec.cat', unpack=True)
    
    if align_data is not None:
        ra_list, dec_list, mag = align_data
            
    im = pyfits.open(sci)
    print sci
    
    sh = im[0].shape
    head = im[0].header
    head['CUNIT1'] = 'deg'; head['CUNIT2'] = 'deg'
    wcs = pywcs.WCS(head)

    x_image, y_image = wcs.wcs_sky2pix(ra_list, dec_list, 1)
    
    try:
        x_image, y_image = wcs.wcs_sky2pix(ra_list, dec_list, 1)
    except:
        x_image, y_image = wcs.wcs_world2pix(ra_list, dec_list, 1)
    
    ok = (x_image > 0) & (y_image > 0) & (x_image < sh[1]) & (y_image < sh[1])

    x_image, y_image = x_image[ok], y_image[ok]
    
    fpr = open('align.reg','w')
    fpr.write('image\n')
    for i in range(ok.sum()): fpr.write('circle(%.6f, %.6f,0.3") # color=magenta\n' %(x_image[i], y_image[i]))
    fpr.close()
    
    # x_image, y_image = [], []
    # 
    # for ra, dec in zip(ra_list, dec_list):
    #     x, y = wcs.wcs_sky2pix([[ra, dec]], 1)[0]
    #     if (x > 0) & (y > 0) & (x < sh[1]) & (y < sh[1]):
    #         x_image.append(x)
    #         y_image.append(y)
    
    alignCat = catIO.EmptyCat()
    alignCat['X_IMAGE'] = np.array(x_image)
    alignCat['Y_IMAGE'] = np.array(y_image)
    
    xshift = 0
    yshift = 0
    rot = 0
    scale = 1.
    
    xrms = 2
    yrms = 2
    
    NITER = 5
    IT = 0
    while (IT < NITER):
        IT = IT+1
        
        #### Get x,y coordinates of detected objects
        ## direct image
        fp = open('direct.xy','w')
        for i in range(len(directCat.X_IMAGE)):
            fp.write('%s  %s\n' %(directCat.X_IMAGE[i],directCat.Y_IMAGE[i]))
        fp.close()

        ## alignment image
        fp = open('align.xy','w')
        for i in range(len(alignCat.X_IMAGE)):
            fp.write('%s  %s\n' %(np.float(alignCat.X_IMAGE[i])+xshift,
                       np.float(alignCat.Y_IMAGE[i])+yshift))
        fp.close()

        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        #### iraf.xyxymatch to find matches between the two catalogs
        pow = toler*1.
        try:
            os.remove('align.match')
        except:
            pass
        status1 = iraf.xyxymatch(input="direct.xy", reference="align.xy",
                       output="align.match",
                       tolerance=2**pow, separation=0, verbose=iraf.yes, Stdout=1)
        
        nmatch = 0
        while status1[-1].startswith('0') | (nmatch < 10) | (float(status1[-3].split()[1]) > 40):
            pow+=1
            os.remove('align.match')
            status1 = iraf.xyxymatch(input="direct.xy", reference="align.xy",
                           output="align.match",
                           tolerance=2**pow, separation=0, verbose=iraf.yes, Stdout=1)
            #
            nmatch = 0
            for line in open('align.match').xreadlines(  ): nmatch += 1
            
        if verbose:
            for line in status1:
                print line
        
                
        #### Compute shifts with iraf.geomap
        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        try:
            os.remove("align.map")
        except:
            pass
            
        status2 = iraf.geomap(input="align.match", database="align.map",
                    fitgeometry=fitgeometry, interactive=iraf.no, 
                    xmin=iraf.INDEF, xmax=iraf.INDEF, ymin=iraf.INDEF, ymax=iraf.INDEF,
                    maxiter = 10, reject = 2.0, Stdout=1)
        if verbose:
            for line in status2:
                print line
        
        #fp = open(root+'.iraf.log','a')
        #fp.writelines(status1)
        #fp.writelines(status2)
        #fp.close()
                
        #### Parse geomap.output 
        fp = open("align.map","r")
        for line in fp.readlines():
            spl = line.split()
            if spl[0].startswith('xshift'):
                xshift += float(spl[1])    
            if spl[0].startswith('yshift'):
                yshift += float(spl[1])    
            if spl[0].startswith('xrotation'):
                rot = float(spl[1])    
            if spl[0].startswith('xmag'):
                scale = float(spl[1])    
            if spl[0].startswith('xrms'):
                xrms = float(spl[1])    
            if spl[0].startswith('yrms'):
                yrms = float(spl[1])    
            
        fp.close()
        
        #os.system('wc align.match')
        print 'Shift iteration #%d, xshift=%f, yshift=%f, rot=%f, scl=%f (rms: %5.2f,%5.2f)' %(IT, xshift, yshift, rot, scale, xrms, yrms)
    
    os.system('cat align.match | grep -v "\#" | grep [0-9] | awk \'{print "circle(", $1, ",", $2, ",4) # color=green"}\' > d.reg')
    os.system('cat align.match | grep -v "\#" | grep [0-9] | awk \'{print "circle(", $3, ",", $4, ",4) # color=magenta"}\' > a.reg')
    
    shutil.copy('align.map', sci.replace('.fits', '.align.map'))
    shutil.copy('align.match', sci.replace('.fits', '.align.match'))
    
    #### Cleanup
    if clean:
        rmfiles = ['align.cat', 'align.map','align.match','align.reg','align.xy', 'direct.cat','direct.reg','direct.xy']
        
        for file in rmfiles:
            try:
                os.remove(file)
            except:
                pass
    
    fp = open(sci.replace('.fits', '.align.info'), 'w')
    fp.write('# image xshift yshift rot scale xrms yrms\n')
    fp.write('%s %.3f %.3f %.4f %.4f %.3f %.3f\n' %(sci, xshift, yshift, rot, scale, xrms, yrms))
    
    if (np.abs(xshift) > shift_max) | (np.abs(yshift) > shift_max) | (xrms > rms_max) | (yrms > rms_max):
        print 'Shifts out of allowed range.  Run again with increased shift_max to accept.'
        #return xshift, yshift, rot, scale, xrms, yrms
        ## Add a small shift that should come out easily with another 
        ## shift iteration
        xshift, yshift, rot, scale, xrms, yrms = 2,2,0,1.0,-99,-99
        
    for file in [sci, wht]:
        if ('r' in fitgeometry) & rot_only:
            xshift, yshift = 0, 0
            
        #apply_offsets(file, [[xshift, yshift, rot, scale]])
        from drizzlepac import updatehdr
        updatehdr.updatewcs_with_shift(file, sci, wcsname='DRZWCS',
                        rot=rot,scale=scale,
                        xsh=xshift, ysh=yshift,
                        fit=None,
                        xrms=xrms, yrms = yrms,
                        verbose=False, force=True, sciext=0)
        
    if '_dr' in sci:
        im = pyfits.open(sci)
        h = im[0].header
        for i in range(h['NDRIZIM']):
            flt_str = h['D%03dDATA' %(i+1)]
            if 'sci,2' in flt_str:
                continue
            #
            flt_im = flt_str.split('[')[0]
            ext = int(flt_str.split('[')[1][:-1].split(',')[1])
            updatehdr.updatewcs_with_shift(flt_im, sci, wcsname='GTWEAK', rot=rot, scale=scale, xsh=xshift, ysh=yshift,
                            fit=None, xrms=xrms, yrms = yrms, verbose=False, force=True, sciext='SCI')
                
        # im = pyfits.open(file, mode='update')
        # wcs = pywcs.WCS(im[0].header)
        # wcs.rotateCD(-rot)
        # wcs.wcs.cd /= scale
        # #
        # im[0].header['CRPIX1'] += xshift
        # im[0].header['CRPIX2'] += yshift
        # #
        # for i in [0,1]:
        #     for j in [0,1]:
        #         im[0].header['CD%d_%d' %(i+1, j+1)] = wcs.wcs.cd[i,j]
        # #        
        # im.flush()
    
    return xshift, yshift, rot, scale, xrms, yrms
예제 #12
0
def align_to_reference(
    ROOT_DIRECT,
    ALIGN_IMAGE,
    fitgeometry="shift",
    clean=True,
    verbose=False,
    ALIGN_EXTENSION=0,
    toler=3,
    skip_swarp=False,
    align_sdss_ds9=False,
    catalog=None,
):
    """
xshift, yshift, rot, scale, xrms, yrms = align_to_reference()
    """
    import os
    import glob
    import shutil

    from pyraf import iraf
    from iraf import stsdas, dither

    import threedhst
    from threedhst import catIO

    no = iraf.no
    yes = iraf.yes
    INDEF = iraf.INDEF

    #### Clean slate
    rmfiles = [
        "SCI.fits",
        "WHT.fits",
        "align.cat",
        "direct.cat" "align.map",
        "align.match",
        "align.reg",
        "align.xy",
        "direct.reg",
        "direct.xy",
        "ds9_align.tsv",
    ]

    for file in rmfiles:
        try:
            os.remove(file)
        except:
            pass

    if catalog is not None:
        align_sdss_ds9 = True

    #### Get only images that overlap from the ALIGN_IMAGE list
    if not align_sdss_ds9:
        align_img_list = find_align_images_that_overlap(
            ROOT_DIRECT + "_drz.fits", ALIGN_IMAGE, ALIGN_EXTENSION=ALIGN_EXTENSION
        )
        if not align_img_list:
            print "threedhst.shifts.align_to_reference: no alignment images overlap."
            return 0, 0

    #### Use swarp to combine the alignment images to the same image
    #### dimensions as the direct mosaic
    if (not skip_swarp) & (not align_sdss_ds9):
        try:
            os.remove(ROOT_DIRECT + "_align.fits")
        except:
            pass
        matchImagePixels(
            input=align_img_list,
            matchImage=ROOT_DIRECT + "_drz.fits",
            output=ROOT_DIRECT + "_align.fits",
            match_extension=1,
            input_extension=ALIGN_EXTENSION,
        )

    #### Run SExtractor on the direct image, with the WHT
    #### extension as a weight image
    se = threedhst.sex.SExtractor()
    se.aXeParams()
    se.copyConvFile()
    se.overwrite = True
    se.options["CHECKIMAGE_TYPE"] = "NONE"
    se.options["WEIGHT_TYPE"] = "MAP_WEIGHT"
    se.options["WEIGHT_IMAGE"] = "WHT.fits"
    se.options["FILTER"] = "Y"
    ## Detect thresholds (default = 1.5)
    THRESH = 10
    if align_sdss_ds9:
        if "Vizier" not in REFERENCE_CATALOG:
            THRESH = 20

    se.options["DETECT_THRESH"] = "%d" % (THRESH)
    se.options["ANALYSIS_THRESH"] = "%d" % (THRESH)
    se.options["MAG_ZEROPOINT"] = str(threedhst.options["MAG_ZEROPOINT"])

    #### Run SExtractor on direct and alignment images
    ## direct image
    se.options["CATALOG_NAME"] = "direct.cat"
    iraf.imcopy(ROOT_DIRECT + "_drz.fits[1]", "SCI.fits")
    iraf.imcopy(ROOT_DIRECT + "_drz.fits[2]", "WHT.fits")
    status = se.sextractImage("SCI.fits")

    ## Read the catalog
    directCat = threedhst.sex.mySexCat("direct.cat")

    if align_sdss_ds9:
        ### Use ds9 SDSS catalog to refine alignment
        import threedhst.dq
        import pywcs
        import threedhst.catIO as catIO

        wcs = pywcs.WCS(pyfits.getheader("SCI.fits", 0))
        # wcs = pywcs.WCS(pyfits.getheader('Q0821+3107-F140W_drz.fits', 1))

        if "Vizier" in REFERENCE_CATALOG:
            #### Use (unstable) astroquery Vizier search
            #### CFHTLS-Deep: 'Vizier.II/317'
            VIZIER_CAT = REFERENCE_CATALOG.split("Vizier.")[1]
            print "Align to Vizier catalog: http://vizier.u-strasbg.fr/viz-bin/VizieR?-source=%s" % (VIZIER_CAT)

            import astroquery

            if astroquery.__version__ < "0.0.dev1078":
                from astroquery import vizier

                query = {}
                query["-source"] = VIZIER_CAT
                # query["-out"] = ["_r", "CFHTLS", "rmag"]
                query["-out"] = ["_RAJ2000", "_DEJ2000"]  ### Just RA/Dec.

                #### Center position and query radius
                r0, d0 = wcs.wcs_pix2sky([[wcs.naxis1 / 2.0, wcs.naxis2 / 2.0]], 1)[0]
                rll, dll = wcs.wcs_pix2sky([[0, 0]], 1)[0]
                corner_radius = (
                    np.sqrt((r0 - rll) ** 2 * np.cos(d0 / 360.0 * 2 * np.pi) ** 2 + (d0 - dll) ** 2) * 60.0 * 1.5
                )
                h = query["-c"] = "%.6f %.6f" % (r0, d0)
                query["-c.rm"] = "%.3f" % (corner_radius)  ### xxx check image size

                #### Run the query
                vt = vizier.vizquery(query)
            else:
                #### Newer astroquery
                from astroquery.vizier import Vizier
                import astropy.coordinates as coord
                import astropy.units as u

                Vizier.ROW_LIMIT = -1

                r0, d0 = wcs.wcs_pix2sky([[wcs.naxis1 / 2.0, wcs.naxis2 / 2.0]], 1)[0]
                rll, dll = wcs.wcs_pix2sky([[0, 0]], 1)[0]
                corner_radius = (
                    np.sqrt((r0 - rll) ** 2 * np.cos(d0 / 360.0 * 2 * np.pi) ** 2 + (d0 - dll) ** 2) * 60.0 * 1.5
                )
                #
                c = coord.ICRSCoordinates(ra=r0, dec=d0, unit=(u.deg, u.deg))
                #### something with astropy.coordinates
                # c.icrs.ra.degree = c.icrs.ra.degrees
                # c.icrs.dec.degree = c.icrs.dec.degrees
                #
                vt = Vizier.query_region(c, width=u.Quantity(corner_radius, u.arcminute), catalog=[VIZIER_CAT])[0]

            #### Make a region file
            ra_list, dec_list = vt["RAJ2000"], vt["DEJ2000"]
            print "Vizier, found %d objects." % (len(ra_list))
            fp = open("%s.vizier.reg" % (ROOT_DIRECT), "w")
            fp.write("# %s, r=%.1f'\nfk5\n" % (VIZIER_CAT, corner_radius))
            for ra, dec in zip(ra_list, dec_list):
                fp.write('circle(%.6f, %.6f, 0.5")\n' % (ra, dec))
            #
            fp.close()
        else:
            #### Use DS9 catalog
            ds9 = threedhst.dq.myDS9()
            ds9.set("file SCI.fits")
            # ds9.set('file Q0821+3107-F140W_drz.fits')
            ds9.set("catalog %s" % (REFERENCE_CATALOG))
            ### Can't find XPA access point for "copy to regions"
            ds9.set("catalog export tsv ds9_align.tsv")
            lines = open("ds9_align.tsv").readlines()
            ra_list, dec_list = [], []
            for line in lines[1:]:
                spl = line.split()
                ra, dec = float(spl[0]), float(spl[1])
                ra_list.append(ra)
                dec_list.append(dec)
            #
            del (ds9)

        x_image, y_image = [], []
        for ra, dec in zip(ra_list, dec_list):
            x, y = wcs.wcs_sky2pix([[ra, dec]], 1)[0]
            x_image.append(x)
            y_image.append(y)

        alignCat = catIO.EmptyCat()
        alignCat["X_IMAGE"] = np.array(x_image)
        alignCat["Y_IMAGE"] = np.array(y_image)

    else:
        ## alignment image
        se.options["CATALOG_NAME"] = "align.cat"
        status = se.sextractImage(ROOT_DIRECT + "_align.fits")
        alignCat = threedhst.sex.mySexCat("align.cat")

    xshift = 0
    yshift = 0
    rot = 0
    scale = 1.0

    xrms = 2
    yrms = 2

    NITER = 5
    IT = 0
    while IT < NITER:
        IT = IT + 1

        #### Get x,y coordinates of detected objects
        ## direct image
        fp = open("direct.xy", "w")
        for i in range(len(directCat.X_IMAGE)):
            fp.write("%s  %s\n" % (directCat.X_IMAGE[i], directCat.Y_IMAGE[i]))
        fp.close()

        ## alignment image
        fp = open("align.xy", "w")
        for i in range(len(alignCat.X_IMAGE)):
            fp.write("%s  %s\n" % (np.float(alignCat.X_IMAGE[i]) + xshift, np.float(alignCat.Y_IMAGE[i]) + yshift))
        fp.close()

        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        #### iraf.xyxymatch to find matches between the two catalogs
        pow = toler * 1.0
        try:
            os.remove("align.match")
        except:
            pass

        status1 = iraf.xyxymatch(
            input="direct.xy",
            reference="align.xy",
            output="align.match",
            tolerance=2 ** pow,
            separation=0,
            verbose=yes,
            Stdout=1,
        )

        nmatch = 0
        while status1[-1].startswith("0") | (nmatch < 10):
            pow += 1
            os.remove("align.match")
            status1 = iraf.xyxymatch(
                input="direct.xy",
                reference="align.xy",
                output="align.match",
                tolerance=2 ** pow,
                separation=0,
                verbose=yes,
                Stdout=1,
            )
            #
            nmatch = 0
            for line in open("align.match").xreadlines():
                nmatch += 1

        if verbose:
            for line in status1:
                print line

        #### Compute shifts with iraf.geomap
        iraf.flpr()
        iraf.flpr()
        iraf.flpr()
        try:
            os.remove("align.map")
        except:
            pass

        status2 = iraf.geomap(
            input="align.match",
            database="align.map",
            fitgeometry=fitgeometry,
            interactive=no,
            xmin=INDEF,
            xmax=INDEF,
            ymin=INDEF,
            ymax=INDEF,
            maxiter=10,
            reject=2.0,
            Stdout=1,
        )
        if verbose:
            for line in status2:
                print line

        # fp = open(root+'.iraf.log','a')
        # fp.writelines(status1)
        # fp.writelines(status2)
        # fp.close()

        #### Parse geomap.output
        fp = open("align.map", "r")
        for line in fp.readlines():
            spl = line.split()
            if spl[0].startswith("xshift"):
                xshift += float(spl[1])
            if spl[0].startswith("yshift"):
                yshift += float(spl[1])
            if spl[0].startswith("xrotation"):
                rot = float(spl[1])
            if spl[0].startswith("xmag"):
                scale = float(spl[1])
            if spl[0].startswith("xrms"):
                xrms = float(spl[1])
            if spl[0].startswith("yrms"):
                yrms = float(spl[1])

        fp.close()

        # os.system('wc align.match')
        print "Shift iteration #%d, xshift=%f, yshift=%f, rot=%f, scl=%f (rms: %5.2f,%5.2f)" % (
            IT,
            xshift,
            yshift,
            rot,
            scale,
            xrms,
            yrms,
        )

    im = pyfits.open("SCI.fits")

    shutil.copy("align.map", ROOT_DIRECT + "_align.map")
    shutil.copy("align.match", ROOT_DIRECT + "_align.match")

    #### Cleanup
    if clean:
        rmfiles = [
            "SCI.fits",
            "WHT.fits",
            "align.cat",
            "align.map",
            "align.match",
            "align.reg",
            "align.xy",
            "direct.cat",
            "direct.reg",
            "direct.xy",
            "drz_sci.fits",
            "drz_wht.fits",
            "bg.fits",
        ]

        for file in rmfiles:
            try:
                os.remove(file)
            except:
                pass

    return xshift, yshift, rot, scale, xrms, yrms
예제 #13
0
def plot_shifts(
    ROOT_DIRECT,
    ALIGN_IMAGE,
    clean=True,
    verbose=True,
    ALIGN_EXTENSION=0,
    toler=3,
    skip_swarp=False,
    threshold=7,
    force=False,
    drz=True,
    WEIGHT_IMAGE=None,
):
    """
    Run SExtractor on two images and match the objects to plot the shifts between them.
    
    ALIGN_IMAGE is a string that may contain wildcards, and the function will use 
    `align_img_list` to find ALIGN_IMAGEs
    """
    import glob

    from pyraf import iraf
    from iraf import stsdas, dither

    no = iraf.no
    yes = iraf.yes
    INDEF = iraf.INDEF

    if os.path.exists(ROOT_DIRECT + "_align.fits") & (not force):
        if verbose:
            print "Image %s_align.fits exists.  Skipping SWarp." % (ROOT_DIRECT)
        skip_swarp = True

    if not skip_swarp:
        if drz:
            align_img_list = find_align_images_that_overlap(
                ROOT_DIRECT + "_drz.fits", ALIGN_IMAGE, ALIGN_EXTENSION=ALIGN_EXTENSION
            )
        else:
            align_img_list = glob.glob(ALIGN_IMAGE)

        if not align_img_list:
            print "threedhst.shifts.align_to_reference: no alignment images overlap."
            return 0, 0
        #
        try:
            os.remove(ROOT_DIRECT + "_align.fits")
        except:
            pass

        if drz:
            matchImagePixels(
                input=align_img_list,
                matchImage=ROOT_DIRECT + "_drz.fits",
                output=ROOT_DIRECT + "_align.fits",
                match_extension=1,
                input_extension=ALIGN_EXTENSION,
            )
            ALIGN_FITS = ROOT_DIRECT + "_align.fits"
        else:
            ALIGN_FITS = os.path.basename(ROOT_DIRECT.split(".fits")[0]) + "_align.fits"
            matchImagePixels(
                input=align_img_list,
                matchImage=ROOT_DIRECT,
                output=ALIGN_FITS,
                match_extension=0,
                input_extension=ALIGN_EXTENSION,
            )

    se = threedhst.sex.SExtractor()
    se.aXeParams()
    se.copyConvFile()
    se.overwrite = True
    se.options["CHECKIMAGE_TYPE"] = "NONE"
    se.options["WEIGHT_TYPE"] = "MAP_WEIGHT"

    if drz:
        se.options["WEIGHT_IMAGE"] = ROOT_DIRECT + "_drz.fits[1]"
    else:
        if WEIGHT_IMAGE:
            se.options["WEIGHT_IMAGE"] = WEIGHT_IMAGE
        else:
            se.options["WEIGHT_TYPE"] = "NONE"
            se.options["WEIGHT_IMAGE"] = "NONE"

    se.options["FILTER"] = "Y"
    ## Detect thresholds (default = 1.5)
    se.options["DETECT_THRESH"] = "%f" % (threshold)
    se.options["ANALYSIS_THRESH"] = "%f" % (threshold)
    se.options["MAG_ZEROPOINT"] = str(threedhst.options["MAG_ZEROPOINT"])

    #### Run SExtractor on direct and alignment images
    ## direct image
    se.options["CATALOG_NAME"] = "direct.cat"
    if drz:
        status = se.sextractImage(ROOT_DIRECT + "_drz.fits[0]")
        INPUT_IMAGE = ROOT_DIRECT + "_drz.fits"
    else:
        status = se.sextractImage(ROOT_DIRECT)
        INPUT_IMAGE = ROOT_DIRECT

    ## alignment image
    se.options["CATALOG_NAME"] = "align.cat"
    se.options["WEIGHT_TYPE"] = "NONE"
    status = se.sextractImage(ALIGN_FITS)

    ## Read the catalogs
    directCat = threedhst.sex.mySexCat("direct.cat")
    alignCat = threedhst.sex.mySexCat("align.cat")

    xshift = 0
    yshift = 0
    rot = 0
    scale = 1.0

    xrms = 2
    yrms = 2

    NITER = 5
    IT = 0
    while IT < NITER:
        IT = IT + 1

        #### Get x,y coordinates of detected objects
        ## direct image
        fp = open("direct.xy", "w")
        for i in range(len(directCat.X_IMAGE)):
            fp.write("%s  %s\n" % (directCat.X_IMAGE[i], directCat.Y_IMAGE[i]))
        fp.close()

        ## alignment image
        fp = open("align.xy", "w")
        for i in range(len(alignCat.X_IMAGE)):
            fp.write("%s  %s\n" % (np.float(alignCat.X_IMAGE[i]) + xshift, np.float(alignCat.Y_IMAGE[i]) + yshift))
        fp.close()

        iraf.flpr()
        iraf.flpr()
        iraf.flpr()

        #### iraf.xyxymatch to find matches between the two catalogs
        pow = toler * 1.0
        try:
            os.remove("align.match")
        except:
            pass

        status1 = iraf.xyxymatch(
            input="direct.xy",
            reference="align.xy",
            output="align.match",
            tolerance=2 ** pow,
            separation=0,
            verbose=yes,
            Stdout=1,
        )

        while status1[-1].startswith("0"):
            pow += 1
            os.remove("align.match")
            status1 = iraf.xyxymatch(
                input="direct.xy",
                reference="align.xy",
                output="align.match",
                tolerance=2 ** pow,
                separation=0,
                verbose=yes,
                Stdout=1,
            )

    #### Images are aligned, plot the offsets

    dx, dy, ax, ay, di, ai = np.loadtxt("align.match", unpack=True)

    ddx, ddy = dx - ax, dy - ay
    keep = (np.abs(ddx) < 15) & (np.abs(ddy) < 15)
    for i in range(5):
        sx, sy = threedhst.utils.biweight(ddx[keep], both=True), threedhst.utils.biweight(ddy[keep], both=True)
        keep = keep & (np.abs(ddx - sx[0]) < 5 * sx[1]) & (np.abs(ddy - sy[0]) < 5 * sy[1])

    if USE_PLOT_GUI:
        fig = plt.figure(figsize=[8, 4], dpi=100)
    else:
        fig = Figure(figsize=[8, 4], dpi=100)

    fig.subplots_adjust(wspace=0.28, hspace=0.0, left=0.08, bottom=0.14, right=0.98, top=0.98)

    ax = fig.add_subplot(121)

    ax.plot(ddx, ddy, marker="o", linestyle="None", color="black", alpha=0.4, ms=2, zorder=-1)
    ax.errorbar(sx[0], sy[0], sx[1], sy[1], marker="o", ms=0.1, color="white", linewidth=3, zorder=100)
    ax.errorbar(sx[0], sy[0], sx[1], sy[1], marker="o", ms=0.1, color="red", linewidth=2, zorder=500)

    ax.grid(alpha=0.5)
    dwin = 5 * np.max([sx[1], sy[1]])
    ax.set_xlim(sx[0] - dwin, sx[0] + dwin)
    ax.set_ylim(sy[0] - dwin, sy[0] + dwin)
    ax.set_xlabel(r"$\Delta x$ [pix]")
    ax.set_ylabel(r"$\Delta y$ [pix]")
    ax.text(0.5, 0.95, os.path.basename(INPUT_IMAGE), fontsize=9, horizontalalignment="center", transform=ax.transAxes)
    ax.text(0.5, 0.9, os.path.basename(ALIGN_IMAGE), fontsize=9, horizontalalignment="center", transform=ax.transAxes)

    ax.text(
        0.5,
        0.1,
        r"$\Delta x, \Delta y = %.2f \pm %.2f, %.2f \pm %.2f)$" % (sx[0], sx[1], sy[0], sy[1]),
        fontsize=11,
        horizontalalignment="center",
        transform=ax.transAxes,
    )

    ax = fig.add_subplot(122)

    ax.plot(dx[keep], dy[keep], marker="o", ms=1, linestyle="None", color="black", alpha=0.1)
    ax.quiver(
        dx[keep],
        dy[keep],
        ddx[keep],
        ddy[keep],
        alpha=0.5,
        angles="xy",
        headlength=1,
        headwidth=1,
        scale=30.0 / (dx.max() - dx.min()),
        units="x",
        minlength=1,
    )
    aa = np.array([1, 1])
    ax.quiver(
        dx[keep].mean() * aa,
        dy[keep].max() * 0.95 * aa,
        1 * aa,
        0 * aa,
        alpha=0.9,
        angles="xy",
        headlength=0,
        headwidth=1,
        scale=30.0 / (dx.max() - dx.min()),
        units="x",
        color="red",
    )

    ax.set_xlabel(r"$x$ [pix]")
    ax.set_ylabel(r"$y$ [pix]")

    if USE_PLOT_GUI:
        fig.savefig(os.path.basename(ROOT_DIRECT.split(".fits")[0]) + "_align.pdf", dpi=100, transparent=False)
    else:
        canvas = FigureCanvasAgg(fig)
        canvas.print_figure(os.path.basename(ROOT_DIRECT.split(".fits")[0]) + "_align.pdf", dpi=100, transparent=False)

    if clean:
        rmfiles = [
            "SCI.fits",
            "WHT.fits",
            "align.cat",
            "align.map",
            "align.match",
            "align.reg",
            "align.xy",
            "direct.cat",
            "direct.reg",
            "direct.xy",
            "drz_sci.fits",
            "drz_wht.fits",
            "bg.fits",
        ]

        for file in rmfiles:
            try:
                os.remove(file)
            except:
                pass
예제 #14
0
def alignimages(im1, im2):
    runsex = 1  #run sextractor to get object catalogs
    auto = 0.
    t = im1.split('.')
    prefixim1 = t[0]
    t = prefixim1.split('pre')
    fieldid = t[0]  #saves cl1018 or whatever as fieldid
    t = im2.split('.')
    prefixim2 = t[0]

    filexy1 = prefixim1 + '-xy.cat'
    filexy2 = prefixim2 + '-xy.cat'
    print "aligning images for ", fieldid
    if runsex > 0:

        runsextractor(im1, auto)
        infile = open('test.cat', 'r')  #keep only sources w/in useable field

        outfile = open(filexy1, 'w')
        for line in infile:  #keep only targets w/in 500 pixels of center
            if line.find('#') > -1:
                continue
            t = line.split()
            out = '%8.4f %8.4f \n' % (float(t[10]), float(t[11]))
            outfile.write(out)
        infile.close()
        outfile.close()

        print "running sextractor on ", im2
        runsextractor(im2, auto)

        infile = open('test.cat', 'r')  #keep only sources w/in useable field

        outfile = open(filexy2, 'w')
        for line in infile:  #keep only targets w/in 500 pixels of center
            if line.find('#') > -1:
                continue
            t = line.split()
            out = '%8.4f %8.4f \n' % (float(t[10]), float(t[11]))
            outfile.write(out)
        infile.close()
        outfile.close()

    match = fieldid + '-match'
    dbase = fieldid + '-match-geomap'
    iraf.display(im1, 1, fill='yes')
    iraf.display(im2, 2, fill='yes')
    reffile = fieldid + 'refpoints'  #make these individually.  First line w/3points in gmos image (x1 y1 x2 y2 x3 y3). 2nd line w/same points in ediscs I-band
    flag = raw_input("Should we create a refpoints file (0=no, 1=yes)?\n")
    flag = int(flag)
    if flag > 0.1:
        s = 'cp cl1018refpoints ' + reffile
        os.system(s)
        print "open ", reffile, " in emacs, delete 2 lines"
        print "Enter x1 y1 x2 y2  x3 y3 for ref image (gmos)"
        print "Enter x1 y1 x2 y2  x3 y3 for 2nd image (vlt)"
        iraf.imexam()

    iraf.xyxymatch(filexy2,
                   filexy1,
                   match,
                   tolerance=15,
                   refpoints=reffile,
                   matching='tolerance',
                   interactive='no')
    iraf.imgets(image=im1, param='i_naxis1')
    t = iraf.imgets.value
    im1xmax = (float(t))
    iraf.imgets(image=im1, param='i_naxis2')
    t = iraf.imgets.value
    im1ymax = (float(t))

    iraf.geomap(input=match,
                database=dbase,
                function='polynomial',
                xmin=1,
                xmax=im1xmax,
                ymin=1,
                ymax=im1ymax,
                xxorder=4,
                xyorder=4,
                yyorder=4,
                yxorder=4,
                transform='gmos',
                interactive='yes')
    transformim = 1
    if transformim > 0:
        outim2 = 'g' + im2
        iraf.geotran(im2, output=outim2, database=dbase, transform='gmos')
        iraf.display(im2, 1, fill='yes')
        iraf.display(outim2, 2, fill='yes')
        iraf.display(im1, 3, fill='yes')