Exemple #1
0
def plot_init(square=True,
              xs=6,
              aspect=1,
              left=0.22,
              bottom=0.11,
              right=0.02,
              top=0.02,
              wspace=0.2,
              hspace=0.02,
              fontsize=10,
              NO_GUI=False,
              use_tex=False,
              invert=False):
    """
    Wrapper for generating a plot window, contains input parameters for setting the 
    full window geometry and also handles toggling the GUI/interactive backend.
    
    NO_GUI should be set to True if your session has no X11 connection.    
    """
    import unicorn
    import matplotlib
    rc = matplotlib.rcParams

    #### If logged in to an external machine ("uni"), don't use GUI plotter
    if unicorn.hostname().startswith('uni') | NO_GUI:
        unicorn.plotting.USE_PLOT_GUI = False
    else:
        unicorn.plotting.USE_PLOT_GUI = True

    # plt.rcParams['font.family'] = 'serif'
    # plt.rcParams['font.serif'] = ['Times']
    plt.rcParams['patch.edgecolor'] = 'None'
    plt.rcParams['font.size'] = fontsize

    plt.rcParams['image.origin'] = 'lower'
    plt.rcParams['image.interpolation'] = 'nearest'

    if use_tex:
        plt.rcParams['text.usetex'] = True
        plt.rcParams['font.family'] = 'serif'
        plt.rcParams['font.serif'] = 'Times'

    #### White on black colormap
    if invert:

        if isinstance(invert, str):
            color = invert
        else:
            color = 'white'

        rc['lines.color'] = color
        rc['patch.edgecolor'] = color
        rc['text.color'] = color
        rc['axes.facecolor'] = 'black'
        rc['axes.edgecolor'] = color
        rc['axes.labelcolor'] = color
        rc['xtick.color'] = color
        rc['ytick.color'] = color
        rc['grid.color'] = color
        rc['figure.facecolor'] = 'black'
        rc['figure.edgecolor'] = 'black'
        rc['savefig.facecolor'] = 'black'
        rc['savefig.edgecolor'] = 'black'
    else:

        rc['lines.color'] = 'black'
        rc['patch.edgecolor'] = 'black'
        rc['text.color'] = 'black'
        rc['axes.facecolor'] = 'white'
        rc['axes.edgecolor'] = 'black'
        rc['axes.labelcolor'] = 'black'
        rc['xtick.color'] = 'black'
        rc['ytick.color'] = 'black'
        rc['grid.color'] = 'black'
        rc['figure.facecolor'] = 'white'
        rc['figure.edgecolor'] = 'white'
        rc['savefig.facecolor'] = 'white'
        rc['savefig.edgecolor'] = 'white'

    if square:
        #xs=5
        lrbt = np.array([left, right, bottom, top]) * 5. / xs
        ys = (1 - lrbt[1] - lrbt[0]) / (1 - lrbt[3] - lrbt[2]) * xs * aspect
        lrbt[[2, 3]] /= aspect

        if USE_PLOT_GUI:
            fig = plt.figure(figsize=(xs, ys), dpi=100)
        else:
            fig = Figure(figsize=(xs, ys), dpi=100)

        fig.subplots_adjust(left=lrbt[0],
                            bottom=lrbt[2],
                            right=1 - lrbt[1],
                            top=1 - lrbt[3],
                            wspace=wspace,
                            hspace=hspace)

    else:
        if USE_PLOT_GUI:
            fig = plt.figure(figsize=(7, 5), dpi=100)
        else:
            fig = Figure(figsize=(7, 5), dpi=100)

        fig.subplots_adjust(wspace=wspace,
                            hspace=hspace,
                            left=0.10,
                            bottom=0.10,
                            right=0.99,
                            top=0.97)

    if invert:
        fig.invert = True
    else:
        fig.invert = False

    return fig
Exemple #2
0
def reduce_acs(root='',LIMITING_MAGNITUDE=20., match_wfc3 = False, WFC3_DIR='/3DHST/Spectra/Release/v2.0/GOODS-S'):
    
    """
    Set parameters for the aXe reduction, run aXe, read photometric catalog, find matches, make plots of spectra with photometry.
    """

    import numpy as np

    field = root[0:-3]
    if LIMITING_MAGNITUDE is None:
        LIMITING_MAGNITUDE=20.

    os_command = 'cp PREP_FLT/'+root+'*shifts.txt PREP_FLT/'+root+'*tweak.fits PREP_FLT/'+root+'*asn.fits DATA/' 
    os.system(os_command)
    
    os.chdir(unicorn.GRISM_HOME+'ACS_PARALLEL/'+field)
    unicorn.go_3dhst.set_parameters(direct='F814W', LIMITING_MAGNITUDE=LIMITING_MAGNITUDE)

    threedhst.process_grism.set_ACS_G800L()
    
    threedhst.options['PREFAB_DIRECT_IMAGE'] = '../PREP_FLT/'+root+'-F814W_drz.fits'
    threedhst.options['PREFAB_GRISM_IMAGE'] = root+'-G800L_drz.fits'
    if threedhst.options['PREFAB_GRISM_IMAGE'] != '': 
        print "Copy PREFAB_GRISM_IMAGE to DATA."
        os.system('cp PREP_FLT/'+threedhst.options['PREFAB_GRISM_IMAGE']+' DATA/')
        
    threedhst.options['FORCE_CATALOG']=root+'.ext.cat'
    ##### Note: segmentation image has to accompany the force_catalog!

    threedhst.process_grism.reduction_script(asn_grism_file=root+'-G800L_asn.fits')
    
    ### SEDs unicorn.analysis.make_SED_plots(grism_root='jbhm51020')
    #os.chdir('../')
    
    ## read photometric, redshift, SPS catalogs
    cat, zout, fout = unicorn.analysis.read_catalogs(root=field)
    cat.star_flag=np.ones(cat.id.size)

    ## path where other eazy outputs live
    OUTPUT_DIRECTORY = os.path.dirname(zout.filename)
    MAIN_OUTPUT_FILE = os.path.basename(zout.filename).split('.zout')[0]
    
    ## read grism outputs
    if unicorn.hostname().startswith('uni'): 
        BASE_PATH='/Volumes/robot/3DHST/Spectra/Work/ACS_PARALLEL/'+field+'/'
    if unicorn.hostname().startswith('hyp'):
        BASE_PATH='/3DHST/Spectra/Work/ACS_PARALLEL/'+field+'/'
    print 'BASE PATH:', BASE_PATH
        
    grism_root = root+'-G800L'    
    grismCat, SPC = unicorn.analysis.read_grism_files(root=grism_root.upper(), BASE_PATH=BASE_PATH, GRISM_NAME='G800L')

    print 'Matched catalog'
    unicorn.analysis.match_grism_to_phot(grism_root=grism_root, 
                  SPC = SPC, cat = cat,
                  grismCat = grismCat, zout = zout, fout = fout, 
                  OUTPUT = './HTML/SED/'+grism_root+'_match.cat',
                  OUTPUT_DIRECTORY=OUTPUT_DIRECTORY,
                  MAIN_OUTPUT_FILE=MAIN_OUTPUT_FILE)
    
    ## make figures
    if match_wfc3:
        for id in grismCat.id:
            print id
            status = unicorn.go_acs.specphot_acs_and_wfc3(id=id, grism_root=grism_root, SPC = SPC, 
                cat = cat,
                grismCat = grismCat, zout = zout, fout = fout, 
                OUT_PATH = './HTML/SED/', OUT_FILE_FORMAT=True, Verbose=False,
                MAIN_OUTPUT_FILE = MAIN_OUTPUT_FILE,
                OUTPUT_DIRECTORY = OUTPUT_DIRECTORY,
                CACHE_FILE = 'Same',GET_WFC3 = True, WFC3_DIR=WFC3_DIR)
    else:
        for id in grismCat.id:
            status = unicorn.analysis.specphot(id=id, grism_root=grism_root, SPC = SPC, 
                cat = cat,
                grismCat = grismCat, zout = zout, fout = fout, 
                OUT_PATH = './HTML/SED/', OUT_FILE_FORMAT=True, Verbose=False,
                MAIN_OUTPUT_FILE = MAIN_OUTPUT_FILE,
                OUTPUT_DIRECTORY = OUTPUT_DIRECTORY,
                CACHE_FILE = 'Same')
    
    unicorn.go_3dhst.clean_up()
Exemple #3
0
def reduce_acs(root='',
               LIMITING_MAGNITUDE=20.,
               match_wfc3=False,
               WFC3_DIR='/3DHST/Spectra/Release/v2.0/GOODS-S'):
    """
    Set parameters for the aXe reduction, run aXe, read photometric catalog, find matches, make plots of spectra with photometry.
    """

    import numpy as np

    field = root[0:-3]
    if LIMITING_MAGNITUDE is None:
        LIMITING_MAGNITUDE = 20.

    os_command = 'cp PREP_FLT/' + root + '*shifts.txt PREP_FLT/' + root + '*tweak.fits PREP_FLT/' + root + '*asn.fits DATA/'
    os.system(os_command)

    os.chdir(unicorn.GRISM_HOME + 'ACS_PARALLEL/' + field)
    unicorn.go_3dhst.set_parameters(direct='F814W',
                                    LIMITING_MAGNITUDE=LIMITING_MAGNITUDE)

    threedhst.process_grism.set_ACS_G800L()

    threedhst.options[
        'PREFAB_DIRECT_IMAGE'] = '../PREP_FLT/' + root + '-F814W_drz.fits'
    threedhst.options['PREFAB_GRISM_IMAGE'] = root + '-G800L_drz.fits'
    if threedhst.options['PREFAB_GRISM_IMAGE'] != '':
        print "Copy PREFAB_GRISM_IMAGE to DATA."
        os.system('cp PREP_FLT/' + threedhst.options['PREFAB_GRISM_IMAGE'] +
                  ' DATA/')

    threedhst.options['FORCE_CATALOG'] = root + '.ext.cat'
    ##### Note: segmentation image has to accompany the force_catalog!

    threedhst.process_grism.reduction_script(asn_grism_file=root +
                                             '-G800L_asn.fits')

    ### SEDs unicorn.analysis.make_SED_plots(grism_root='jbhm51020')
    #os.chdir('../')

    ## read photometric, redshift, SPS catalogs
    cat, zout, fout = unicorn.analysis.read_catalogs(root=field)
    cat.star_flag = np.ones(cat.id.size)

    ## path where other eazy outputs live
    OUTPUT_DIRECTORY = os.path.dirname(zout.filename)
    MAIN_OUTPUT_FILE = os.path.basename(zout.filename).split('.zout')[0]

    ## read grism outputs
    if unicorn.hostname().startswith('uni'):
        BASE_PATH = '/Volumes/robot/3DHST/Spectra/Work/ACS_PARALLEL/' + field + '/'
    if unicorn.hostname().startswith('hyp'):
        BASE_PATH = '/3DHST/Spectra/Work/ACS_PARALLEL/' + field + '/'
    print 'BASE PATH:', BASE_PATH

    grism_root = root + '-G800L'
    grismCat, SPC = unicorn.analysis.read_grism_files(root=grism_root.upper(),
                                                      BASE_PATH=BASE_PATH,
                                                      GRISM_NAME='G800L')

    print 'Matched catalog'
    unicorn.analysis.match_grism_to_phot(grism_root=grism_root,
                                         SPC=SPC,
                                         cat=cat,
                                         grismCat=grismCat,
                                         zout=zout,
                                         fout=fout,
                                         OUTPUT='./HTML/SED/' + grism_root +
                                         '_match.cat',
                                         OUTPUT_DIRECTORY=OUTPUT_DIRECTORY,
                                         MAIN_OUTPUT_FILE=MAIN_OUTPUT_FILE)

    ## make figures
    if match_wfc3:
        for id in grismCat.id:
            print id
            status = unicorn.go_acs.specphot_acs_and_wfc3(
                id=id,
                grism_root=grism_root,
                SPC=SPC,
                cat=cat,
                grismCat=grismCat,
                zout=zout,
                fout=fout,
                OUT_PATH='./HTML/SED/',
                OUT_FILE_FORMAT=True,
                Verbose=False,
                MAIN_OUTPUT_FILE=MAIN_OUTPUT_FILE,
                OUTPUT_DIRECTORY=OUTPUT_DIRECTORY,
                CACHE_FILE='Same',
                GET_WFC3=True,
                WFC3_DIR=WFC3_DIR)
    else:
        for id in grismCat.id:
            status = unicorn.analysis.specphot(
                id=id,
                grism_root=grism_root,
                SPC=SPC,
                cat=cat,
                grismCat=grismCat,
                zout=zout,
                fout=fout,
                OUT_PATH='./HTML/SED/',
                OUT_FILE_FORMAT=True,
                Verbose=False,
                MAIN_OUTPUT_FILE=MAIN_OUTPUT_FILE,
                OUTPUT_DIRECTORY=OUTPUT_DIRECTORY,
                CACHE_FILE='Same')

    unicorn.go_3dhst.clean_up()
Exemple #4
0
def plot_init(square=True, xs=6, aspect=1, left=0.22, bottom=0.11, right=0.02, top=0.02, wspace=0.2, hspace=0.02, fontsize=10, NO_GUI=False, use_tex=False, invert=False):
    """
    Wrapper for generating a plot window, contains input parameters for setting the 
    full window geometry and also handles toggling the GUI/interactive backend.
    
    NO_GUI should be set to True if your session has no X11 connection.    
    """
    import unicorn
    import matplotlib
    rc = matplotlib.rcParams
    
    #### If logged in to an external machine ("uni"), don't use GUI plotter
    if unicorn.hostname().startswith('uni') | NO_GUI:
        unicorn.plotting.USE_PLOT_GUI = False
    else:
        unicorn.plotting.USE_PLOT_GUI = True
    
    # plt.rcParams['font.family'] = 'serif'
    # plt.rcParams['font.serif'] = ['Times']
    plt.rcParams['patch.edgecolor'] = 'None'
    plt.rcParams['font.size'] = fontsize

    plt.rcParams['image.origin'] = 'lower'
    plt.rcParams['image.interpolation'] = 'nearest'

    if use_tex:
        plt.rcParams['text.usetex'] = True
        plt.rcParams['font.family'] = 'serif'
        plt.rcParams['font.serif'] = 'Times'
    
    #### White on black colormap
    if invert:

        if isinstance(invert, str):
            color = invert
        else:
            color = 'white'
        
        rc['lines.color'] = color
        rc['patch.edgecolor'] = color
        rc['text.color'] = color
        rc['axes.facecolor'] = 'black'
        rc['axes.edgecolor'] = color
        rc['axes.labelcolor'] = color
        rc['xtick.color'] = color
        rc['ytick.color'] = color
        rc['grid.color'] = color
        rc['figure.facecolor'] = 'black'
        rc['figure.edgecolor'] = 'black'
        rc['savefig.facecolor'] = 'black'
        rc['savefig.edgecolor'] = 'black'
    else:

        rc['lines.color'] = 'black'
        rc['patch.edgecolor'] = 'black'
        rc['text.color'] = 'black'
        rc['axes.facecolor'] = 'white'
        rc['axes.edgecolor'] = 'black'
        rc['axes.labelcolor'] = 'black'
        rc['xtick.color'] = 'black'
        rc['ytick.color'] = 'black'
        rc['grid.color'] = 'black'
        rc['figure.facecolor'] = 'white'
        rc['figure.edgecolor'] = 'white'
        rc['savefig.facecolor'] = 'white'
        rc['savefig.edgecolor'] = 'white'
        
    if square:
        #xs=5
        lrbt = np.array([left,right,bottom,top])*5./xs     
        ys = (1-lrbt[1]-lrbt[0])/(1-lrbt[3]-lrbt[2])*xs*aspect
        lrbt[[2,3]] /= aspect

        if USE_PLOT_GUI:
            fig = plt.figure(figsize=(xs,ys), dpi=100)
        else:
            fig = Figure(figsize=(xs,ys), dpi=100)
            
        fig.subplots_adjust(left=lrbt[0], bottom=lrbt[2], right=1-lrbt[1], top=1-lrbt[3], wspace=wspace, hspace=hspace)
            
    else:
        if USE_PLOT_GUI:
            fig = plt.figure(figsize=(7,5), dpi=100)
        else:
            fig = Figure(figsize=(7,5), dpi=100)
            
        fig.subplots_adjust(wspace=wspace, hspace=hspace,left=0.10,
                        bottom=0.10,right=0.99,top=0.97)        
    
    if invert:
        fig.invert = True
    else:
        fig.invert = False
        
    return fig
Exemple #5
0
def interlace_combine_acs(root='jbhm19010',
                          view=True,
                          use_error=True,
                          make_undistorted=False,
                          pad=120,
                          NGROW=0,
                          ddx=0,
                          ddy=0,
                          growx=1,
                          growy=1,
                          auto_offsets=False,
                          chip=1,
                          filter='F814W',
                          outroot='UDS-19',
                          center=None,
                          file_ext='flc'):
    """
    Combine four dithered ACS exposures in an interlaced image, but use the same native ACS pixel grid
    since the dither offsets don't evenly sample the ACS pixel.  This also simplifies the image distortions
    to following the native definitions.
    
    Input is a visit ID which will read the attached ASN table.  FLT images should be destriped and CTE corrected
    and run through [Multi/Astro]Drizzle to flag CRs (DQ=4096).
    
    Provide `filter` and `outroot` keywords to rename the visit name to something more meaningful.
    
    Make separate images for each chip, note [SCI,1] is CCDCHIP=2, [SCI,2] is CCDCHIP=1.
    """
    # from pyraf import iraf
    # #from iraf import iraf
    # from iraf import dither
    #
    import threedhst.prep_flt_files
    import unicorn.reduce as red

    chip_ext = {1: 2, 2: 1}  ### Chip1 is SCI,2 and Chip2 is SCI,1 extensions

    if unicorn.hostname().startswith('uni'):
        view = False

    if view:
        import threedhst.dq
        ds9 = threedhst.dq.myDS9()

    #
    asn = threedhst.utils.ASNFile(root + '_asn.fits')
    flt = pyfits.open(asn.exposures[0] + '_%s.fits' % (file_ext))

    ### Works for WFC3/G280
    if flt[0].header['INSTRUME'] == 'WFC3':
        NX, NY = 4096, 2051
        im = pyfits.open(os.getenv('iref') + 'UVIS%dwfc3_map.fits' % (chip))
        PAM = im[1].data
        im.close()
    else:
        NX, NY = 4096, 2048
        im = pyfits.open(os.getenv('jref') + 'wfc%d_pam.fits' % (chip))
        PAM = im[0].data
        im.close()

    #PAM = flt[1].data*0.+1

    if os.path.exists(root + '.run'):
        run = threedhst.prep_flt_files.MultidrizzleRun(root)
        #run.blot_back(ii=0, copy_new=True)
        scl = np.float(run.scl)
        xsh, ysh = threedhst.utils.xyrot(
            np.array(run.xsh) * scl,
            np.array(run.ysh) * scl, run.rot[0])
    else:
        xsh, ysh = np.zeros(len(asn.exposures)), np.zeros(len(asn.exposures))

    yi, xi = np.indices((NY, NX))

    #pad += NGROW*4

    N = np.zeros((NY * growy + pad + growy * 2 * NGROW,
                  NX * growx + pad + growx * 2 * NGROW),
                 dtype=np.int)

    inter_sci = np.zeros((NY * growy + pad + growy * 2 * NGROW,
                          NX * growx + pad + growx * 2 * NGROW))
    inter_weight = np.zeros((NY * growy + pad + growy * 2 * NGROW,
                             NX * growx + pad + growx * 2 * NGROW))
    # if use_error:
    #     inter_err = np.zeros((NY*growy+pad+growy*2*NGROW, NX*growx+pad+growx*2*NGROW))

    xi += pad / (2 * growx) + NGROW
    yi += pad / (2 * growy) + NGROW

    #### Interlaced offsets
    dxs, dys = unicorn.reduce.acs_interlace_offsets(root + '_asn.fits',
                                                    growx=growx,
                                                    growy=growy,
                                                    path_to_flt='./',
                                                    chip=chip)

    dxs, dys = np.append(dxs, dxs), np.append(dys, dys)

    if center is not None:
        if not isinstance(center, list):
            center_coords = [
                flt['SCI', chip_ext[chip]].header['CRVAL1'],
                flt['SCI', chip_ext[chip]].header['CRVAL2']
            ]
        else:
            center_coords = center

        from drizzlepac import skytopix
        import astropy.coordinates as co
        import astropy.units as u

        ext = [None, 4, 1][chip]
        xpix, ypix = np.zeros(len(asn.exposures)), np.zeros(len(asn.exposures))
        for i, exp in enumerate(asn.exposures):
            rd = co.FK5(ra=center_coords[0],
                        dec=center_coords[1],
                        unit=(u.deg, u.deg))
            rdst = str(rd.to_string()).replace('s', '')
            for r in 'hdm':
                rdst = rdst.replace(r, ':')
            #
            xpix[i], ypix[i] = skytopix.rd2xy('%s_%s.fits[sci,%d]' %
                                              (exp, file_ext, chip_ext[chip]),
                                              rdst.split()[0],
                                              rdst.split()[1],
                                              verbose=False)
        #
        dxs = -np.cast[int](np.round(xpix - xpix[0]))
        dys = -np.cast[int](np.round(ypix - ypix[0]))

    dxs += ddx
    dys += ddy

    print 'Offsets:', dxs, dys, '\n'

    #### Find hot pixels, which are flagged as cosmic
    #### rays at the same location in each of the flt files.  Ignore others.
    hot_pix = np.zeros((NY, NX), dtype='int')

    for flt in asn.exposures:
        im = pyfits.open(flt + '_%s.fits' % (file_ext))
        hot_pix += (im['DQ', chip_ext[chip]].data & 4096) / 4096

    hot_pix = hot_pix > (len(asn.exposures) - 2)

    for i, flt in enumerate(asn.exposures):
        print flt
        #flt = run.flt[i]
        im = pyfits.open(flt + '_%s.fits' % (file_ext))
        #ds9.frame(i+1); ds9.view(im[1].data); ds9.scale(0,5)

        #### Use the pixel area map correction
        im['SCI', chip_ext[chip]].data *= PAM

        #### Divide by 4 to conserve surface brightness with smaller output pixels
        im['SCI', chip_ext[chip]].data /= 1. * (growx * growy)
        im['ERR', chip_ext[chip]].data /= 1. * (growx * growy)

        ### Mask cosmic rays
        if i == 0:
            h0 = im[0].header
            h1 = im['SCI', chip_ext[chip]].header
            #header = red.scale_header_wcs(h1.copy(), factor=2, growx=growx, growy=growy, pad=pad)
            header = h1.copy()
            header_wht = header.copy()
            if pyfits.__version__ < '3.3':
                header.update('EXTNAME', 'SCI')
                #header.update('PAD',pad)
                header.update('REFIMAGE', '', comment='Source detection image')
                header_wht.update('EXTNAME', 'ERR')
            else:
                header['EXTNAME'] = 'SCI'
                #header.update('PAD',pad)
                header['REFIMAGE'] = ('', 'Source detection image')
                header_wht['EXTNAME'] = 'ERR'

        dx = np.int(np.round((xsh[i] - xsh[0]) * growx))
        dy = np.int(np.round((ysh[i] - ysh[0]) * growy))
        #
        dx = dxs[i]
        dy = dys[i]
        #
        #use = ((im[3].data & 4096) == 0) & ((im[3].data & 4) == 0) #& (xi > np.abs(dx/2)) & (xi < (1014-np.abs(dx/2))) & (yi > np.abs(dy/2)) & (yi < (1014-np.abs(dy/2)))
        #
        use = ((im['DQ', chip_ext[chip]].data &
                (4 + 32 + 16 + 128 + 1024 + 2048 + 4096)) == 0) & (~hot_pix)

        #### preparation step doesn't subtract background
        im['SCI',
           chip_ext[chip]].data -= np.median(im['SCI',
                                                chip_ext[chip]].data[use])
        im['SCI', chip_ext[chip]].data /= im[0].header['EXPTIME']
        im['ERR', chip_ext[chip]].data /= im[0].header['EXPTIME']

        #inter_sci[yi[use]*growy+dy,xi[use]*growx+dx] += im['SCI',chip_ext[chip]].data[use]
        inter_sci[yi[use] * growy + dy, xi[use] * growx +
                  dx] += im['SCI', chip_ext[chip]].data[use] / im[
                      'ERR', chip_ext[chip]].data[use]**2
        inter_weight[yi[use] * growy + dy, xi[use] * growx +
                     dx] += 1. / im['ERR', chip_ext[chip]].data[use]**2

        N[yi[use] * growy + dy, xi[use] * growx + dx] += 1

        # if use_error:
        #     inter_err[yi[use]*growy+dy,xi[use]*growx+dx] += im['ERR',chip_ext[chip]].data[use]**2

        if view:
            ds9.view_array(inter_sci / np.maximum(N, 1), header=header)
            ds9.scale(-0.1, 5)

    #### Average for case when dither positions overlap, e.g. CANDELS SN fields
    # inter_sci /= np.maximum(N,1)
    # inter_err = np.sqrt(inter_err) / np.maximum(N, 1)
    # inter_err[N == 0] = 0.
    inter_weight[inter_weight == 0] = 1
    inter_sci = inter_sci / inter_weight
    inter_err = np.sqrt(1. / inter_weight)
    inter_err[N == 0] = 0.

    if use_error:
        h0.update('WHTERROR', True, comment='WHT extension is FLT[err,1]')
    else:
        h0.update('WHTERROR',
                  False,
                  comment='WHT extension is 0/1 flagged bad pix')

    ### Clip back to native size
    # inter_sci = inter_sci[pad/2:-pad/2, pad/2:-pad/2]
    # inter_err = inter_err[pad/2:-pad/2, pad/2:-pad/2]
    # N = N[pad/2:-pad/2, pad/2:-pad/2]
    header['PAD'] = pad
    header['GROWX'] = growx
    header['GROWY'] = growy
    header['NGROW'] = NGROW
    header['CRPIX1'] += pad / 2.
    header['CRPIX2'] += pad / 2.

    #print pad, inter_sci.shape

    hdu = pyfits.PrimaryHDU(header=h0)
    sci = pyfits.ImageHDU(data=np.cast[np.float32](inter_sci), header=header)
    if use_error:
        wht = pyfits.ImageHDU(data=np.cast[np.float32](inter_err),
                              header=header_wht)
    else:
        wht = pyfits.ImageHDU(data=np.cast[np.int](N), header=header_wht)

    image = pyfits.HDUList([hdu, sci, wht])
    if 'EXTEND' not in hdu.header.keys():
        hdu.header.update('EXTEND', True, after='NAXIS')

    image[0].header.update('FILTER', filter)
    if outroot is None:
        outroot = root

    image.writeto('%s-chip%d-%s_inter.fits' % (outroot, chip, filter),
                  clobber=True)

    if 0:
        flt = pyfits.open('jbhj07yfq_flt.fits')
        inter = pyfits.open('GOODS-S-7-chip2-F814W_inter.fits')
        ds9.view(flt[1].data / flt[0].header['EXPTIME'] -
                 inter[1].data[pad:-pad, pad:-pad])