Beispiel #1
0
def run(fields, targetSN, bins=None, Nsim=30, run_parallel=False):
    """ Interface to calculate the errors of the Lick indices. """
    for field in fields:
        os.chdir(os.path.join(data_dir, "combined_{0}".format(field)))
        specs = "binned_sn{0}.fits".format(targetSN)
        data = pf.getdata(specs)
        w = wavelength_array(specs, axis=1, extension=0)
        ssps_file = os.path.join(templates_dir, 'miles_FWHM_2.51.fits')
        ssps = pf.getdata(ssps_file, 0)
        wssps = np.power(np.e, pf.getdata(ssps_file, 1))
        databins = wavelength_array(specs, axis=2, extension=0)
        os.chdir(os.path.join(data_dir, "combined_{0}".format(field),
                              "logs_sn{0}".format(targetSN)))
        ######################################################################
        # If bins are not specified, then look for all available bins
        if bins == None:
            bins = databins
        ######################################################################
        if run_parallel:
            pool = mp.Pool()
            for bin in bins:
                spec = data[bin - 1]
                pool.apply_async(run_mc,
                                 args=(field, bin, w, spec, wssps, ssps, Nsim))
            pool.close()
            pool.join()
        else:
            for bin in bins:
                spec = data[bin - 1]
                run_mc(field, bin, w, spec, wssps, ssps, Nsim)
Beispiel #2
0
def calc_extent(image, extension=1):
    h = pf.getheader(image)
    ra = wavelength_array(image, axis=1, extension=extension)
    dec = wavelength_array(image, axis=2, extension=extension)
    ra0 = 159.178471651
    dec0 = -27.5281283035
    # Ofset to the center of NGC 3311
    ra -= ra0
    dec -= dec0
    # Convert to radians
    X = D * 1000 * np.deg2rad(ra)
    Y = D * 1000 * np.deg2rad(dec)
    # Scale to the distance of the cluster
    extent = np.array([X[0], X[-1], Y[0], Y[-1]])
    return extent
def slice_cube(r):
    """ Slice field A cube around the center within a given radius in kpc. """
    ###########################################################################
    # Input files
    cubefile = "output_zap.fits"
    imfile="NGC3311_FieldA_exp1_(white)_IMAGE_FOV_2014-12-27T07:52:48.469.fits"
    ###########################################################################
    # Setting up the parameters of the new cube
    ps = 0.262 # kpc / arcsec
    rarcsec = r / ps
    center = np.array([dec0, ra0])
    ymin, xmin = center - rarcsec / 3600.
    ymax, xmax = center + rarcsec / 3600.
    wave = wavelength_array(cubefile, axis=3, extension=1)
    wmin, wmax = wave[0], wave[1800]
    ###########################################################################
    # Loading data and processing
    im = Image(imfile)
    cube = Cube(cubefile)
    ###########################################################################
    # Peocessing data
    im2 = im.truncate(ymin, ymax, xmin, xmax)
    outim = "NGC3311_FieldA_{0}kpc_image.fits".format(r)
    im2.write(outim)
    outcube = "NGC3311_FieldA_{0}kpc_cube.fits".format(r)
    cube2 = cube.truncate([wmin, ymin, xmin, wmax, ymax, xmax])
    cube2.write(outcube)
    return
Beispiel #4
0
def calc_mag_ab(targetSN, w1, w2):
    """Calculates the AB magnitudes of the bins"""
    for field, sn in zip(fields, targetSN):
        os.chdir(os.path.join(data_dir, "combined_{0}".format(field)))
        fits = "binned_sn{0}_res2.95.fits".format(sn)
        data = pf.getdata(fits, 0)
        w = wavelength_array(fits, axis=1, extension=0) * u.angstrom
        idx = np.where(((w >= w1 * u.angstrom) & (w < w2 * u.angstrom)))
        data = data[:,idx]
        w = w[idx]
        bins = wavelength_array(fits, axis=2, extension=0)
        lines = []
        for i, bin in enumerate(bins):
            f_lambda = data[i]  * np.power(10., -20) * u.erg / u.s / u.cm / u.cm / u.angstrom
            f_lambda = f_lambda.to("erg * s**-1 * cm**-3")
            f_nu = f_lambda * w.to("cm") * w.to("cm") / c.to("cm * Hz")
            m_ab = -2.5 * np.log10(np.median(f_nu.to("Jy")/ (3631 * u.Jy)))
            mv = m_ab - 3
            id = "{0}_bin{1:04d}".format(field, bin)
            line = "{0:20s}{1:10.4f}{2:10.4f}".format(id, m_ab, mv)
            lines.append(line)
        with open("magab_w{0}_{1}.dat".format(w1, w2), "w") as f:
            f.write("\n".join(lines))
Beispiel #5
0
def run(fields, targetSN, w1, w2):
    global velscale
    bandsfile = os.path.join(tables_dir, "bands.txt")
    bands = np.loadtxt(bandsfile, usecols=np.arange(2, 8))
    types = np.loadtxt(bandsfile, usecols=(8,))
    tempfile = os.path.join(home, "MILES10.0/templates/templates_w{0}_{1}_res2.95.fits".format(w1, w2))
    ssps = pf.getdata(tempfile, 0).T
    wssps = np.exp(wavelength_array(tempfile, axis=1, extension=0))
    for field in fields:
        os.chdir(os.path.join(data_dir, "combined_{0}".format(field)))
        specs = "binned_sn{0}.fits".format(targetSN)
        data = pf.getdata(specs)
        w = wavelength_array(specs, axis=1, extension=0)
        bins = wavelength_array(specs, axis=2, extension=0)
        for bin in bins:
            print "Working on bin {0}".format(bin)
            spec = data[bin - 1]
            pp = ppload("logs_sn{0}_w{3}_{4}/{1}_bin{2:04d}".format(targetSN, field, bin, w1, w2))
            pp = pPXF(pp, velscale)
            ##################################################################
            # Produce bestfit templates convolved with LOSVD/redshifted
            # Make the combination
            ssps_unbroad_v0 = ssps.dot(pp.w_ssps)
            ssps_broad = losvd_convolve(ssps_unbroad_v0, pp.sol[0])
            ssps_unbroad = losvd_convolve(ssps_unbroad_v0, np.array([pp.sol[0][0], 0.1 * velscale, 0, 0]))
            ##################################################################
            # Interpolate bestfit templates to obtain linear dispersion
            b0 = interp1d(wssps, ssps_unbroad, kind="linear", fill_value="extrapolate", bounds_error=False)
            b1 = interp1d(wssps, ssps_broad, kind="linear", fill_value="extrapolate", bounds_error=False)
            best_unbroad = b0(w)
            best_broad = b1(w)
            ##################################################################
            # Correct for emission lines
            em = interp1d(pp.w, pp.gas, kind="linear", bounds_error=False, fill_value=0.0)
            emission = em(w)
            spec -= emission
            ###################################################################
            # Correct for extinction
            # spec /= reddening_curve(w, pp.reddening)
            ###################################################################
            # Run the lector
            l = Lick(w, spec, bands, vel=pp.sol[0][0])
            lunb = Lick(w, best_unbroad, bands, vel=pp.sol[0][0])
            lbest = Lick(w, best_broad, bands, vel=pp.sol[0][0])
            ##################################################################
            # LOSVD correction using best fit templates
            ##################################################################
            lickc = correct_lick(types, l.classic, lunb.classic, lbest.classic)
            ################################################################
            # Convert to string
            ################################################################
            lick = "".join(["{0:14}".format("{0:.5f}".format(x)) for x in l.classic])
            lickc = "".join(["{0:14}".format("{0:.5f}".format(x)) for x in lickc])
            #     # Append to output
            logfile1 = "logs_sn{0}_w{3}_{4}/lick_{1}_bin{2:04d}" "_raw.txt".format(targetSN, field, bin, w1, w2)
            logfile2 = "logs_sn{0}_w{3}_{4}/lick_{1}_bin{2:04d}" "_corr.txt".format(targetSN, field, bin, w1, w2)
            with open(logfile1, "w") as f:
                f.write("{0:16s}".format(pp.name) + lick + "\n")
            with open(logfile2, "w") as f:
                f.write("{0:16s}".format(pp.name) + lickc + "\n")
    return
Beispiel #6
0
def run_mc(fields, targetSN, w1, w2, nsim=100, redo=False):
    """ Perform Monte Carlo simulations to calculate uncertainties. """
    global velscale
    bandsfile = os.path.join(tables_dir, "bands.txt")
    bands = np.loadtxt(bandsfile, usecols=np.arange(2, 8))
    types = np.loadtxt(bandsfile, usecols=(8,))
    tempfile = os.path.join(home, "MILES10.0/templates/templates_w{0}_{1}_res2.95.fits".format(w1, w2))
    ssps = pf.getdata(tempfile, 0).T
    wssps = np.exp(wavelength_array(tempfile, axis=1, extension=0))
    for field in fields:
        os.chdir(os.path.join(data_dir, "combined_{0}".format(field)))
        specs = "binned_sn{0}.fits".format(targetSN)
        w = wavelength_array(specs, axis=1, extension=0)
        bins = wavelength_array(specs, axis=2, extension=0)
        for bin in bins:
            print "Working on {1} bin {0}".format(bin, field)
            logfile = "logs_sn{0}_w{3}_{4}/lick_{1}_bin{2:04d}" "_mcerr.txt".format(targetSN, field, bin, w1, w2)
            if os.path.exists(logfile) and not redo:
                continue
            try:
                pp = ppload("logs_sn{0}_w{3}_{4}/{1}_bin{2:04d}".format(targetSN, field, bin, w1, w2))
                pp = pPXF(pp, velscale)
                sol = pp.sol[0]
                error = pp.error[0]
                ##################################################################
                # Produce composite stellar population
                csp = ssps.dot(pp.w_ssps)
                ##################################################################
                # Setup simulations
                vpert = np.random.normal(sol[0], np.maximum(error[0], 10), nsim)
                sigpert = np.random.normal(sol[1], np.maximum(error[1], 10), nsim)
                h3pert = np.random.normal(sol[2], np.maximum(error[2], 0.02), nsim)
                h4pert = np.random.normal(sol[3], np.maximum(error[3], 0.02), nsim)
                losvdsim = np.column_stack((vpert, sigpert, h3pert, h4pert))
                licksim = np.zeros((nsim, 25))
                ##################################################################
                for i, losvd in enumerate(losvdsim):
                    noise = np.random.normal(0.0, pp.noise, len(wssps))
                    bestsim = losvd_convolve(csp, losvd)
                    bestsim_unb = losvd_convolve(csp, np.array([losvd[0], 0.1 * losvd[1], 0, 0]))
                    galsim = bestsim + noise
                    ##############################################################
                    # Run the lector
                    lsim = Lick(wssps, galsim, bands, vel=losvd[0])
                    lunb = Lick(wssps, bestsim_unb, bands, vel=losvd[0])
                    lbest = Lick(wssps, bestsim, bands, vel=losvd[0])
                    ##############################################################
                    # LOSVD correction using best fit templates
                    ##############################################################
                    licksim[i] = correct_lick(types, lsim.classic, lunb.classic, lbest.classic)
                stds = np.zeros(25)
                for i in range(25):
                    if np.all(np.isnan(licksim[:, i])):
                        stds[i] = np.nan
                    else:
                        stds[i] = np.nanstd(sigma_clip(licksim[:, i], sigma=5))
                errors = ["{0:.5g}".format(x) for x in stds]
                errors = "".join(["{0:12s}".format(x) for x in errors])
                ###################################################################
                # Storing results
                with open(logfile, "w") as f:
                    f.write("{0:16s}".format(pp.name) + errors + "\n")
            except:
                print "Problem on bin {0}".format(bin)
                continue
Beispiel #7
0
def run_ppxf(fields, w1, w2, targetSN, tempfile, logdir, redo=False,
             ncomp=2, **kwargs):
    """ New function to run pPXF. """
    global velscale
    stars = pf.getdata(tempfile, 0)
    emission = pf.getdata(tempfile, 1)
    logLam_temp = wavelength_array(tempfile, axis=1, extension=0)
    ngas = len(emission)
    nstars = len(stars)
    templates = np.column_stack((stars.T, emission.T))
    ##########################################################################
    # Set components
    if ncomp == 1:
        components = np.zeros(nstars + ngas)
        kwargs["component"] = components
    elif ncomp == 2:
        components = np.hstack((np.zeros(nstars), np.ones(ngas))).astype(int)
        kwargs["component"] = components
    ##########################################################################
    for f in fields:
        print "Working on Field {0}".format(f[-1])
        os.chdir(os.path.join(data_dir, "combined_{0}".format(f)))
        outdir = os.path.join(os.getcwd(), logdir)
        if not os.path.exists(outdir):
            os.mkdir(outdir)
        fits = "binned_sn{0}_res2.95.fits".format(targetSN)
        data = pf.getdata(fits, 0)
        w = wavelength_array(fits, axis=1, extension=0)
        bins = wavelength_array(fits, axis=2, extension=0)
        ######################################################################
        # Slice array before fitting
        idx = np.where(np.logical_and(w >= w1, w <= w2))[0]
        data = data[:,idx]
        w = w[idx]
        ######################################################################
        for i,bin in enumerate(bins):
            output = os.path.join(outdir, "{1}_bin{2:04d}.pkl".format(targetSN,
                                                                      f, bin))
            outroot = output.replace(".pkl", "")
            if os.path.exists(output) and not redo:
                continue
            print "PPXF run {0}/{1}".format(i+1, len(bins))
            spec = data[i,:]
            signal, noise, sn = snr(spec)
            galaxy, logLam, vtemp = util.log_rebin([w[0], w[-1]],             \
                                                      spec, velscale=velscale)
            dv = (logLam_temp[0]-logLam[0])*c
            lam = np.exp(logLam)
            name = "{0}_bin{1:04d}".format(f, bin)
            noise =  np.ones_like(galaxy) * noise
            kwargs["lam"] = lam
            ###################################################################
            # Masking bad pixels
            skylines = np.array([5577,5889, 6300, 6863])
            goodpixels = np.arange(len(lam))
            for line in skylines:
                sky = np.argwhere((lam < line - 10) | (lam > line + 10)).ravel()
                goodpixels = np.intersect1d(goodpixels, sky)
            kwargs["goodpixels"] = goodpixels
            ###################################################################
            kwargs["vsyst"] = dv
            pp = ppxf(templates, galaxy, noise, velscale, **kwargs)
            title = "Field {0} Bin {1}".format(f[-1], bin)
            pp.name = name
            # Adding other things to the pp object
            pp.has_emission = True
            pp.dv = dv
            pp.w = np.exp(logLam)
            pp.velscale = velscale
            pp.ngas = ngas
            pp.ntemplates = nstars
            pp.templates = 0
            pp.id = id
            pp.name = name
            pp.title = title
            ppsave(pp, outroot=outroot)
            ppf = ppload(outroot)
            ppf = pPXF(ppf, velscale)
            ppf.plot("{1}/{0}.png".format(name, outdir))
    return
Beispiel #8
0
    return p[0] * np.exp(-((w-p[1])/p[2])**2)

def model(p, w):
    return gaussian(p[:3], w) + gaussian(p[3:6], w) + gaussian(p[6:9], w) + \
           p[9] + p[10]*w + p[11]*w*w +  p[12] * w**3 + p[13] * w**4

def residue(p, s, w):
    return (model(p,w) - s)

if __name__ == "__main__":
    targetSN = 70
    for field in fields:
        os.chdir(os.path.join(data_dir, "combined_{0}".format(field)))
        fits = "binned_sn{0}.fits".format(targetSN)
        data = pf.getdata(fits, 0)
        wave = wavelength_array(fits, axis=1, extension=0)
        w1, w2 = 6600, 6700
        idx = np.where((wave >= w1) & (wave <= w2))[0]

        bins = wavelength_array(fits, axis=2, extension=0)
        p0 = np.array([500, 6645, 3, 450, 6630, 3, 450, 6666, 3, 350, 1, 0.1, -0.01, 0 ])
        for bin in bins:
            plt.plot(wave[idx], data[bin,:][idx], "-k")
            plt.minorticks_on()
            pfit = leastsq(residue, p0, args=(data[bin,:][idx],wave[idx]))[0]
            print pfit[0] * pfit[2] * np.sqrt(2 * np.pi)
            # plt.plot(wave[idx], model(pfit, wave[idx]), "-r")
            plt.xlabel("Wavelength (\AA)")
            plt.ylabel(r"Flux ($10^{-20}$ erg s$^{-1}$ cm$^{-2} \AA^{-1}$)")
            plt.show()
            plt.clf()