Exemplo n.º 1
0
def cutout(filename='', hdu=None, center=[None, None],im_size=0.1,pix=False,
           writepdf=False, writefits=False, silent=False):
    '''
    >> sub_hdu = cutout(filename='file.fits', center=[12,-1.], im_size=0.1,
                                        writepdf=False, writefits=False)
    >> sub_hdu = cutout(hdu=hdu, center=[12,-1.], im_size=0.1,
                                        writepdf=False, writefits=False
    returns:
      pyfits.core.PrimaryHDU 
    input:
     - hdu (pyfits.core.HDUList or pyfits.core.PrimaryHDU ) or filename of fits image
     - center=[ra,dec] (deg)
     - im_size=0.1 (deg)
    optional input:
     - pix input center and im_size are in pixel units
     - writepdf='name.pdf' or True (write filename_sub.pdf)
     - writefits='name.fits' or True (fileanme+sub.fits

    the creation of new WCS header doesnt seem to work for all cases...
    '''

    if (filename=='') and not(hdu):
        print 'please give filename= or hdu='
        return
    if not(hdu) and not(os.path.isfile(filename)):
        print 'file :'+ filename+ '\n not found' 
        return
    
    if not np.isscalar(center[0]):
        print 'please give center=[ra, dec]'
        return

    center = np.array(center)

    # read or index to PrimaryHDU 
    if not(hdu):
        hdu = pyfits.open(filename)[0]
    elif type(hdu) == pyfits.core.HDUList:
        hdu = hdu[0]
    elif type(hdu) != pyfits.core.PrimaryHDU:
        print 'type(hdu:)', type(hdu)
        print 'ERROR: type(hdu) needs to be <pyfits.core.HDUList> or pyfits.core.PrimaryHDU'
        return

    # get image
    im = hdu.data
    
    #  get WCS,
    if not(pix):
        wcs = pywcs.WCS(header=hdu.header,  naxis=2) #fobj=hdulist,
    

        if not silent: print 'image shape', im.shape
        if (len(im.shape) == 3):
            if not silent: print 'using first layer of image'
            im = im[0,:,:]
            print 'new image shape', im.shape
        if (len(im.shape) == 4):
            if not silent: print 'using first layer of image'
            im = im[0,0,:,:]
            if not silent: print 'new image shape', im.shape

        # conver center en overplot coordinates
        #pcenter = (wcs.wcs_sky2pix([center], 1))[0] # if pywcs
        pcenter = (wcs.wcs_world2pix([center],0))[0] # if astropy.wcs 
    else:
        pcenter = center


    # slice the image
    if not silent: print 'center in pixel coordinates', pcenter

    # use true sky location (creates non-square images)
    #delta_ax1 = (np.abs(wcs.wcs_sky2pix([ [center[0]-im_size, center[1]] ], 1) - pcenter)/2.)[0][0]
    #delta_ax2 = (np.abs(wcs.wcs_sky2pix([ [center[0], center[1]-im_size] ], 1) - pcenter)/2.)[0][1]
    #delta = [delta_ax1, delta_ax2]
    #delta=  np.abs(wcs.wcs_sky2pix( [center-im_size], 1)[0] - pcenter)/2.

    # use pixel scale to define boundaries
    if not(pix):
        delta = np.abs(0.5*im_size / np.array([hdu.header['CDELT1'], hdu.header['CDELT2']]))
    else:
        delta = (im_size/2., im_size/2.)

    ax1l = pcenter[0]-delta[0]
    ax1u=pcenter[0]+delta[0]
    ax2l = pcenter[1]-delta[1]
    ax2u=pcenter[1]+delta[1]

    # check limits
    if (ax1l < 0): ax1l = 0
    if (ax1u > im.shape[1]): ax1u = im.shape[1]
    if (ax2l < 0): ax2l = 0
    if (ax2u > im.shape[0]): ax2u = im.shape[0]

    if not silent: print 'ax2l,ax2u, ax1l,ax1u', ax2l,ax2u,ax1l,ax1u

    subim = im[ax2l:ax2u,ax1l:ax1u ]

    if not silent: print 'subim shape:',subim.shape
    if min(subim.shape) == 0:
        print 'ERROR. something is wrong with the cutout (center+/-im_size out of bounds?) '
        return None

    # set the base of the output file 
    if (writepdf==True) or (writefits==True):
        srem = ['.FITS', '.FIT', '.fit', '.fits']
        outname = filename
        for srm in srem: outname=outname.split(srm)[0]
        if filename =='':
            print 'warning, not filename given pdf or fits file, using IAU name'
            outname = iau_name(center[0], center[1])
        if not silent: print 'base for output file:', outname
            

    if writepdf:
        # determine color range, we use arcsinh scaling
        scaled_subim = np.arcsinh(subim)
        vals = scaled_subim.reshape(subim.shape[0]*subim.shape[1])
        #nbins=50
        #h_vals = np.histogram(np.log10(vals), new=False, bins=nbins)
        svals = np.sort(vals)
        slen = len(svals)
        vmin = svals[0.01*slen]
        vmax = svals[0.99*slen] #np.power(10, h_vals[1][nbins-10])
        plt.imshow(scaled_subim, vmin=vmin, vmax=vmax,
                   cmap='hot', interpolation='bilinear')

        # set filename (if not given)
        if not(type(writepdf) is str):
            outfile = outname+'_sub.pdf'
        else: outfile = writepdf
        if not silent: print 'writing', outfile
        plt.savefig(outfile, format='pdf')

    #make new WCS and save fits
    sub_hdr = hdu.header.copy() #sub_hdu.header

    ## this wrong: slightly rotates the image
    #sub_hdr['CRVAL1'] = center[0]
    #sub_hdr['CRVAL2'] = center[1]
    #sub_hdr['CRPIX1'] = pcenter[0]-ax1l
    #sub_hdr['CRPIX2'] = pcenter[1]-ax2l

    ## keep CRVAL1 the same, but swift its pixel coodindates
    sub_hdr['CRPIX1'] = np.floor(hdu.header['CRPIX1'] - ax1l ) +1
    sub_hdr['CRPIX2'] = np.floor(hdu.header['CRPIX2'] - ax2l ) +1
    if not silent: print 'orgininal CRVAL (', hdu.header['CRVAL1'], hdu.header['CRVAL2'],\
                              ') in sub image pixel coordindates:', sub_hdr['CRPIX1'] , sub_hdr['CRPIX2'] 

    # note, after this call sub_hdu.header is differnt the input than sub_hdr
    # (eg, NAXIS, NAXIS1, are updated) 
    sub_hdu = pyfits.PrimaryHDU(data=subim, header=sub_hdr)

    # write files
    if writefits:
        if not(type(writefits) is str):
            outfile = outname+'_sub.fits'
        else: outfile = writefits
        if not silent: print 'writing:', outfile
        sub_hdu.writeto(outfile,clobber=True)


    return sub_hdu
Exemplo n.º 2
0
def get_dss(ra, dec, size=1/60., name=None, sdir=None, color='red',
            debug=False, noclobber=False):
    '''
     wrapper to get the DSS image, requires that dss2 application is installed
    (see http://archive.eso.org/cms/tools-documentation/the-eso-st-ecf-digitized-sky-survey-application)
    >> fitsim = get_dss(ra, dec, size=1/60., name=None, sdir=None, color='red')
   
    input:
     ra, dec, size in degree
     sdir: location to save image, default is sjoert.catdir/DSS/fits/
     name: image name default is name dss+pl_Id (pl_Id=dss plate naming convention)
     color: blue, red, IR
    '''

    change_name = True
    if name is None:
        name = 'dss'
        change_name = False
    name = name
    
    if sdir is None:
        sdir = dirs.catdir+'DSS/fits/'
        indir = dirs.catdir+'DSS/infiles/' #keep log somewhere else
    else:
        indir=sdir

    new_name = sdir+name+'.fits'
    if noclobber and os.path.isfile(new_name):
        print 'not rerunning, reading:', new_name
        hdu = pyfits.open(new_name)
        return hdu


    infile_name = indir+name+'.in'
    logfile_name = indir+name+'.log'
    errfile_name = indir+name+'.err'

    infile = file(infile_name,'w')

    sradec = string2radec.radec2string(ra, dec)
    sra = sradec[0:11]
    sdec = sradec[11:]

    long_sra = sra[0:2]+' '+sra[3:5]+' '+sra[6:]
    long_sdec = sdec[0:3]+' '+sdec[4:6]+' '+sdec[7:]
    long_ssize = str(size*60)+' '+str(size*60)

    line =name+'  '+long_sra+' '+long_sdec+ ' '+long_ssize        

    infile.writelines(line+ ' \n')
    infile.close()
    
    command_line = 'cd '+sdir+' ; dss2 '+color+' -i '+infile_name +' > '+logfile_name #+' 2> '+ errfile_name

    command_line = 'dss2 '+color+' -i '+infile_name #+' > '+logfile_name #+' 2> '+ errfile_name

    if debug:
        print sradec
        print line
        print command_line

    #p = subprocess.Popen(command_line, shell=True)
    #t = os.popen(command_line)
    #p = subprocess.call(command_line, shell=True)

    os.system('touch '+logfile_name)
    logfile = open(logfile_name, 'r')

    args = shlex.split(command_line)
    if debug: print  args
    #p3 = subprocess.call('dss2 red -i /Users/sjoertvanvelzen/Documents/project/catalogs/DSS/fits/sjoert.in', shell=True)
    proc = subprocess.Popen(args, cwd=sdir, stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

    sleep_time = (size*60)
    if sleep_time <10: sleep_time = 10
    print 'sleeping for (s):', sleep_time
    time.sleep(sleep_time )
    # at this point we either have an image, or we give up
    proc.terminate()
    
    if proc.wait() < 0:
        
        print 'problem with dss call'
        print 'id:', proc.pid
        #proc.kill()
        #os.kill(proc.pid,  signal.SIGHUP) # doesn't work ?
        return None
    #time.sleep(1)
    #proc.kill()


    #stdout_value = proc.communicate()[0]
    stderr_value = proc.stderr.read()
    print 'stderr:', stderr_value
    stdout_value = proc.stdout.read()


    if debug:
        print '\n stdout: ', stdout_value

    lines = (stdout_value).split('\n')

    if not(len(lines)):
        print 'empty log file', logfile_name
        return None

    i=0
    while not re.search("Field", lines[i]) and (i < (len(lines)-1)):
        i+=1

    if i == (len(lines)-3):
        print 'no info from log file:',logfile_name
        return None

    info_line = lines[i+2].split()
    if len(info_line) < 7:
        print 'no info on plate id:', info_line
        return None
    
    Pl_Id = lines[i+2].split()[8].swapcase()
    if debug: print 'Pl_Id:', Pl_Id
    force_name = sdir+name[0:20]+Pl_Id+'.fits' # max 20 characters...
    if debug: print 'dss image name:', force_name
    
    if change_name:
        os.system('mv '+force_name+' '+new_name)
        if debug: print 'new name:', new_name

        try:
            hdu = pyfits.open(new_name)
            print 'created:', new_name
        except IOError:
            print 'file not created:', new_name
            return None

    else: 
        try:
            hdu = pyfits.open(force_name)
            print 'created:', force_name
        except IOError:
            print 'file not created:', force_name
            return None
        
    return hdu