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)
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
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))
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
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
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
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()