def nearIR(distance, logAge, redlawClass=RedLawNishiyama09, AKsGrid=None): """ For a sampling of effective temperatures and extinctions, calculate the J, H, K, Kp, Ks, Lp magnitudes for a population at the specified distance and age. All output is stored in a pickle file. Input Parameters: distance in pc logAge Optional Input Parameters: redlawClass - default = RedLawNishiyama09 AKsGrid -- default [0 - 5; 0.1 steps] Output stored in a pickle file named syn_nir_d#####_a####.dat. """ pickleFile = 'syn_nir_d' + str(distance).zfill(5) + '_a' \ + str(int(round(logAge*100))).zfill(3) + '.dat' # Get solar mettalicity models for a population at a specific age. evol = evolution.get_merged_isochrone(logAge=logAge) mass = evol.mass logT = evol.logT logg = evol.logg logL = evol.logL temp = 10**logT isWR = evol.logT != evol.logT_WR print 'nearIR: Getting rid of Wolf-Rayet stars, we cannot model their atmospheres' # First get rid of the WR stars, we can't connect atmospheres # to them anyhow. idx = np.where(isWR == False)[0] mass = mass[idx] logT = logT[idx] logg = logg[idx] logL = logL[idx] temp = temp[idx] isWR = isWR[idx] # Sample only 100 points along the whole isochrone interval = int(math.floor(len(mass) / 100.0)) idx = np.arange(0, len(mass), interval, dtype=int) # Make sure to get the last point if idx[-1] != (len(mass) - 1): idx = np.append(idx, len(mass) - 1) mass = mass[idx] logT = logT[idx] logg = logg[idx] logL = logL[idx] temp = temp[idx] # We will also run through a range of extinctions if AKsGrid == None: AKsGrid = np.arange(0, 5, 0.1) # Fetch earth, vega, and extinction objects earth = EarthAtmosphere() vega = Vega() redlaw = redlawClass() # Get the transmission curve for NIRC2 filters and atmosphere. J_filter, J_flux0, J_mag0 = get_filter_info('J', earth, vega) H_filter, H_flux0, H_mag0 = get_filter_info('H', earth, vega) K_filter, K_flux0, K_mag0 = get_filter_info('K', earth, vega) Kp_filter, Kp_flux0, Kp_mag0 = get_filter_info('Kp', earth, vega) Ks_filter, Ks_flux0, Ks_mag0 = get_filter_info('Ks', earth, vega) Lp_filter, Lp_flux0, Lp_mag0 = get_filter_info('Lp', earth, vega) # Output magnitudes for each temperature and extinction value. J = np.zeros((len(temp), len(AKsGrid)), dtype=float) H = np.zeros((len(temp), len(AKsGrid)), dtype=float) K = np.zeros((len(temp), len(AKsGrid)), dtype=float) Kp = np.zeros((len(temp), len(AKsGrid)), dtype=float) Ks = np.zeros((len(temp), len(AKsGrid)), dtype=float) Lp = np.zeros((len(temp), len(AKsGrid)), dtype=float) # For each filter, lets pre-make reddening curves so we only # have to do the calculation once. J_red = [] H_red = [] K_red = [] Kp_red = [] Ks_red = [] Lp_red = [] print 'Making extinction curves' for aa in range(len(AKsGrid)): red = redlaw.reddening(AKsGrid[aa]) J_red.append(red.resample(J_filter.wave)) H_red.append(red.resample(H_filter.wave)) K_red.append(red.resample(K_filter.wave)) Kp_red.append(red.resample(Kp_filter.wave)) Ks_red.append(red.resample(Ks_filter.wave)) Lp_red.append(red.resample(Lp_filter.wave)) # For each temperature extract the synthetic photometry. for ii in range(len(temp)): gravity = logg[ii] L = 10**(logL[ii]) * c.Lsun # luminosity in erg/s T = temp[ii] # in Kelvin # Get the radius R = math.sqrt(L / (4.0 * math.pi * c.sigma * T**4)) # in cm R /= (c.cm_in_AU * c.AU_in_pc) # in pc print 'M = %6.2f Msun T = %5d R = %2.1f Rsun logg = %4.2f' % \ (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii]) # Get the atmosphere model now. Wavelength is in Angstroms star = atm.get_merged_atmosphere(temperature=T, gravity=gravity) # Trim wavelength range down to JHKL range (1.0 - 4.25 microns) star = spectrum.trimSpectrum(star, 10000, 42500) # Convert into flux observed at Earth (unreddened) star *= (R / distance)**2 # in erg s^-1 cm^-2 A^-1 for aa in range(len(AKsGrid)): print 'Photometry for T = %5d, AKs = %3.1f' % \ (temp[ii], AKsGrid[aa]) # ---------- # Now to the filter integrations # ---------- # K J[ii, aa] = mag_in_filter(star, J_filter, J_red[aa], J_flux0, J_mag0) H[ii, aa] = mag_in_filter(star, H_filter, H_red[aa], H_flux0, H_mag0) K[ii, aa] = mag_in_filter(star, K_filter, K_red[aa], K_flux0, K_mag0) Kp[ii, aa] = mag_in_filter(star, Kp_filter, Kp_red[aa], Kp_flux0, Kp_mag0) Ks[ii, aa] = mag_in_filter(star, Ks_filter, Ks_red[aa], Ks_flux0, Ks_mag0) Lp[ii, aa] = mag_in_filter(star, Lp_filter, Lp_red[aa], Lp_flux0, Lp_mag0) # Save output to pickle file pf = open(pickleFile, 'w') pickle.dump(mass, pf) pickle.dump(logg, pf) pickle.dump(logL, pf) pickle.dump(temp, pf) pickle.dump(AKsGrid, pf) pickle.dump(J, pf) pickle.dump(H, pf) pickle.dump(K, pf) pickle.dump(Kp, pf) pickle.dump(Ks, pf) pickle.dump(Lp, pf) return pickleFile
def plot_cmd(): iso = syn.load_isochrone(logAge=logAge, AKs=AKs, distance=distance) mag = iso.mag153m color = iso.mag127m - iso.mag153m idx1 = np.abs(iso.M - 1.0).argmin() idx01 = np.abs(iso.M - 0.1).argmin() py.clf() py.plot(color, mag, 'k.') py.plot(color[idx1], mag[idx1], 'r^', ms=20) py.plot(color[idx01], mag[idx01], 'r^', ms=20) py.xlabel('F127M - F153M') py.ylabel('F153M') py.gca().set_ylim(py.gca().get_ylim()[::-1]) py.savefig('/u/jlu/work/arches/cmd_sim.png') py.clf() py.semilogx(iso.T, iso.logL, 'k.') py.gca().set_xlim(py.gca().get_xlim()[::-1]) py.plot(iso.T[idx1], iso.logL[idx1], 'r^', ms=20) py.plot(iso.T[idx01], iso.logL[idx01], 'r^', ms=20) py.xlabel('Teff (K)') py.ylabel('log(L/Lsun') py.savefig('/u/jlu/work/arches/hr_sim.png') wave = np.array([1.27, 1.39, 1.53]) py.clf() py.plot(wave, [iso.mag127m[idx1], iso.mag139m[idx1], iso.mag153m[idx1]], 'r-') py.plot(wave, [iso.mag127m[idx01], iso.mag139m[idx01], iso.mag153m[idx01]], 'b-') py.savefig('/u/jlu/work/arches/sed.png') c = constants # Convert luminosity to erg/s L_all = 10**(iso.logL) * c.Lsun # luminsoity in erg/s # Calculate radius R_all = np.sqrt(L_all / (4.0 * math.pi * c.sigma * iso.T**4)) R_all /= (c.cm_in_AU * c.AU_in_pc) # Get the atmosphere model now. Wavelength is in Angstroms star1 = atm.get_merged_atmosphere(temperature=iso.T[idx1], gravity=iso.logg[idx1]) # Convert into flux observed at Earth (unreddened) star1 *= (R_all[idx1] / distance)**2 # in erg s^-1 cm^-2 A^-1 # Get the atmosphere model now. Wavelength is in Angstroms star01 = atm.get_merged_atmosphere(temperature=iso.T[idx01], gravity=iso.logg[idx01]) # Convert into flux observed at Earth (unreddened) star01 *= (R_all[idx01] / distance)**2 # in erg s^-1 cm^-2 A^-1 py.clf() py.semilogy(star1.wave, star1.flux, 'r-') py.plot(star01.wave, star01.flux, 'b-') py.xlim(10000, 20000) py.ylim(5e-19, 1e-16) py.savefig('/u/jlu/work/arches/spectra.png')
def make_observed_isochrone_hst_test(logAge, AKs=defaultAKs, k=3, distance=defaultDist, verbose=False): redlaw_k = RedLawNishiyama09(k=k) isoDir = 'iso_k{0}'.format(k) startTime = time.time() print('Making isochrone: log(t) = %.2f AKs = %.2f dist = %d' % \ (logAge, AKs, distance)) print(' Starting at: ', datetime.datetime.now(), ' Usually takes ~5 minutes') outFile = '/u/jlu/work/wd1/models/' + isoDir + '/' outFile += 'iso_%.2f_hst_%4.2f_%4s.pickle' % (logAge, AKs, str(distance).zfill(4)) c = constants # Get solar mettalicity models for a population at a specific age. evol = evolution.get_merged_isochrone(logAge=logAge) # Lets do some trimming down to get rid of repeat masses or # mass resolutions higher than 1/1000. We will just use the first # unique mass after rounding by the nearest 0.001. mass_rnd = np.copy(evol.mass) idx = np.where(evol.mass > 10)[0] mass_rnd[idx] = np.round(evol.mass[idx], decimals=0) print(mass_rnd[0:10]) mass_rnd = np.round(mass_rnd, decimals=1) print(mass_rnd[0:10]) tmp, idx = np.unique(mass_rnd, return_index=True) print('Number of stars {0}'.format(len(idx))) mass = evol.mass[idx] logT = evol.logT[idx] logg = evol.logg[idx] logL = evol.logL[idx] isWR = logT != evol.logT_WR[idx] temp = 10**logT # Output magnitudes for each temperature and extinction value. mag814w = np.zeros(len(temp), dtype=float) mag125w = np.zeros(len(temp), dtype=float) mag139m = np.zeros(len(temp), dtype=float) mag160w = np.zeros(len(temp), dtype=float) filt814w = get_filter_info('acs,f814w,wfc1') filt125w = get_filter_info('wfc3,ir,f125w') filt139m = get_filter_info('wfc3,ir,f139m') filt160w = get_filter_info('wfc3,ir,f160w') # Make reddening red814w = redlaw_k.reddening(AKs).resample(filt814w.wave) red125w = redlaw_k.reddening(AKs).resample(filt125w.wave) red139m = redlaw_k.reddening(AKs).resample(filt139m.wave) red160w = redlaw_k.reddening(AKs).resample(filt160w.wave) # Convert luminosity to erg/s L_all = 10**(logL) * c.Lsun # luminsoity in erg/s # Calculate radius R_all = np.sqrt(L_all / (4.0 * math.pi * c.sigma * temp**4)) R_all /= (c.cm_in_AU * c.AU_in_pc) # For each temperature extract the synthetic photometry. for ii in range(len(temp)): gravity = logg[ii] L = L_all[ii] # in erg/s T = temp[ii] # in Kelvin R = R_all[ii] # in pc # Get the atmosphere model now. Wavelength is in Angstroms star = atm.get_merged_atmosphere(temperature=T, gravity=gravity) # Trim wavelength range down to JHKL range (0.5 - 4.25 microns) star = spectrum.trimSpectrum(star, 5000, 42500) # Convert into flux observed at Earth (unreddened) star *= (R / distance)**2 # in erg s^-1 cm^-2 A^-1 # ---------- # Now to the filter integrations # ---------- mag814w[ii] = mag_in_filter(star, filt814w, red814w) mag125w[ii] = mag_in_filter(star, filt125w, red125w) mag139m[ii] = mag_in_filter(star, filt139m, red139m) mag160w[ii] = mag_in_filter(star, filt160w, red160w) if verbose: print('M = %7.3f Msun T = %5d K R = %2.1f Rsun logg = %4.2f F814W = %4.2f F125W = %4.2f F139M = %4.2f F160W = %4.2f' % \ (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii], mag814w[ii], mag125w[ii], mag139m[ii], mag160w[ii])) iso = objects.DataHolder() iso.M = mass iso.T = temp iso.logg = logg iso.logL = logL iso.mag814w = mag814w iso.mag125w = mag125w iso.mag139m = mag139m iso.mag160w = mag160w iso.isWR = isWR _out = open(outFile, 'wb') pickle.dump(mass, _out) pickle.dump(temp, _out) pickle.dump(logg, _out) pickle.dump(logL, _out) pickle.dump(mag814w, _out) pickle.dump(mag125w, _out) pickle.dump(mag139m, _out) pickle.dump(mag160w, _out) pickle.dump(isWR, _out) _out.close() endTime = time.time() print(' Time taken: %d seconds' % (endTime - startTime))
def nearIR(distance, logAge, redlawClass=RedLawNishiyama09, AKsGrid=None): """ For a sampling of effective temperatures and extinctions, calculate the J, H, K, Kp, Ks, Lp magnitudes for a population at the specified distance and age. All output is stored in a pickle file. Input Parameters: distance in pc logAge Optional Input Parameters: redlawClass - default = RedLawNishiyama09 AKsGrid -- default [0 - 5; 0.1 steps] Output stored in a pickle file named syn_nir_d#####_a####.dat. """ pickleFile = 'syn_nir_d' + str(distance).zfill(5) + '_a' \ + str(int(round(logAge*100))).zfill(3) + '.dat' # Get solar mettalicity models for a population at a specific age. evol = evolution.get_merged_isochrone(logAge=logAge) mass = evol.mass logT = evol.logT logg = evol.logg logL = evol.logL temp = 10**logT isWR = evol.logT != evol.logT_WR print 'nearIR: Getting rid of Wolf-Rayet stars, we cannot model their atmospheres' # First get rid of the WR stars, we can't connect atmospheres # to them anyhow. idx = np.where(isWR == False)[0] mass = mass[idx] logT = logT[idx] logg = logg[idx] logL = logL[idx] temp = temp[idx] isWR = isWR[idx] # Sample only 100 points along the whole isochrone interval = int(math.floor(len(mass) / 100.0)) idx = np.arange(0, len(mass), interval, dtype=int) # Make sure to get the last point if idx[-1] != (len(mass) - 1): idx = np.append(idx, len(mass) - 1) mass = mass[idx] logT = logT[idx] logg = logg[idx] logL = logL[idx] temp = temp[idx] # We will also run through a range of extinctions if AKsGrid == None: AKsGrid = np.arange(0, 5, 0.1) # Fetch earth, vega, and extinction objects earth = EarthAtmosphere() vega = Vega() redlaw = redlawClass() # Get the transmission curve for NIRC2 filters and atmosphere. J_filter, J_flux0, J_mag0 = get_filter_info('J', earth, vega) H_filter, H_flux0, H_mag0 = get_filter_info('H', earth, vega) K_filter, K_flux0, K_mag0 = get_filter_info('K', earth, vega) Kp_filter, Kp_flux0, Kp_mag0 = get_filter_info('Kp', earth, vega) Ks_filter, Ks_flux0, Ks_mag0 = get_filter_info('Ks', earth, vega) Lp_filter, Lp_flux0, Lp_mag0 = get_filter_info('Lp', earth, vega) # Output magnitudes for each temperature and extinction value. J = np.zeros((len(temp), len(AKsGrid)), dtype=float) H = np.zeros((len(temp), len(AKsGrid)), dtype=float) K = np.zeros((len(temp), len(AKsGrid)), dtype=float) Kp = np.zeros((len(temp), len(AKsGrid)), dtype=float) Ks = np.zeros((len(temp), len(AKsGrid)), dtype=float) Lp = np.zeros((len(temp), len(AKsGrid)), dtype=float) # For each filter, lets pre-make reddening curves so we only # have to do the calculation once. J_red = [] H_red = [] K_red = [] Kp_red = [] Ks_red = [] Lp_red = [] print 'Making extinction curves' for aa in range(len(AKsGrid)): red = redlaw.reddening(AKsGrid[aa]) J_red.append( red.resample(J_filter.wave) ) H_red.append( red.resample(H_filter.wave) ) K_red.append( red.resample(K_filter.wave) ) Kp_red.append( red.resample(Kp_filter.wave) ) Ks_red.append( red.resample(Ks_filter.wave) ) Lp_red.append( red.resample(Lp_filter.wave) ) # For each temperature extract the synthetic photometry. for ii in range(len(temp)): gravity = logg[ii] L = 10**(logL[ii]) * c.Lsun # luminosity in erg/s T = temp[ii] # in Kelvin # Get the radius R = math.sqrt(L / (4.0 * math.pi * c.sigma * T**4)) # in cm R /= (c.cm_in_AU * c.AU_in_pc) # in pc print 'M = %6.2f Msun T = %5d R = %2.1f Rsun logg = %4.2f' % \ (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii]) # Get the atmosphere model now. Wavelength is in Angstroms star = atm.get_merged_atmosphere(temperature=T, gravity=gravity) # Trim wavelength range down to JHKL range (1.0 - 4.25 microns) star = spectrum.trimSpectrum(star, 10000, 42500) # Convert into flux observed at Earth (unreddened) star *= (R / distance)**2 # in erg s^-1 cm^-2 A^-1 for aa in range(len(AKsGrid)): print 'Photometry for T = %5d, AKs = %3.1f' % \ (temp[ii], AKsGrid[aa]) # ---------- # Now to the filter integrations # ---------- # K J[ii, aa] = mag_in_filter(star, J_filter, J_red[aa], J_flux0, J_mag0) H[ii, aa] = mag_in_filter(star, H_filter, H_red[aa], H_flux0, H_mag0) K[ii, aa] = mag_in_filter(star, K_filter, K_red[aa], K_flux0, K_mag0) Kp[ii, aa] = mag_in_filter(star, Kp_filter, Kp_red[aa], Kp_flux0, Kp_mag0) Ks[ii, aa] = mag_in_filter(star, Ks_filter, Ks_red[aa], Ks_flux0, Ks_mag0) Lp[ii, aa] = mag_in_filter(star, Lp_filter, Lp_red[aa], Lp_flux0, Lp_mag0) # Save output to pickle file pf = open(pickleFile, 'w') pickle.dump(mass, pf) pickle.dump(logg, pf) pickle.dump(logL, pf) pickle.dump(temp, pf) pickle.dump(AKsGrid, pf) pickle.dump(J, pf) pickle.dump(H, pf) pickle.dump(K, pf) pickle.dump(Kp, pf) pickle.dump(Ks, pf) pickle.dump(Lp, pf) return pickleFile
def make_observed_isochrone_hst(logAge, AKs=defaultAKs, distance=defaultDist, verbose=False): startTime = time.time() print 'Making isochrone: log(t) = %.2f AKs = %.2f dist = %d' % \ (logAge, AKs, distance) print ' Starting at: ', datetime.datetime.now(), ' Usually takes ~5 minutes' outFile = '/u/jlu/work/arches/models/iso/' outFile += 'iso_%.2f_hst_%4.2f_%4s.pickle' % (logAge, AKs, str(distance).zfill(4)) c = constants # Get solar mettalicity models for a population at a specific age. evol = evolution.get_merged_isochrone(logAge=logAge) # Lets do some trimming down to get rid of repeat masses or # mass resolutions higher than 1/1000. We will just use the first # unique mass after rounding by the nearest 0.001. mass_rnd = np.round(evol.mass, decimals=2) tmp, idx = np.unique(mass_rnd, return_index=True) mass = evol.mass[idx] logT = evol.logT[idx] logg = evol.logg[idx] logL = evol.logL[idx] isWR = logT != evol.logT_WR[idx] temp = 10**logT # Output magnitudes for each temperature and extinction value. mag127m = np.zeros(len(temp), dtype=float) mag139m = np.zeros(len(temp), dtype=float) mag153m = np.zeros(len(temp), dtype=float) magH = np.zeros(len(temp), dtype=float) magKp = np.zeros(len(temp), dtype=float) magLp = np.zeros(len(temp), dtype=float) filt127m = get_filter_info('wfc3,ir,f127m') filt139m = get_filter_info('wfc3,ir,f139m') filt153m = get_filter_info('wfc3,ir,f153m') filtH = get_filter_info('nirc2,H') filtKp = get_filter_info('nirc2,Kp') filtLp = get_filter_info('nirc2,Lp') # Make reddening red127m = redlaw.reddening(AKs).resample(filt127m.wave) red139m = redlaw.reddening(AKs).resample(filt139m.wave) red153m = redlaw.reddening(AKs).resample(filt153m.wave) redH = redlaw.reddening(AKs).resample(filtH.wave) redKp = redlaw.reddening(AKs).resample(filtKp.wave) redLp = redlaw.reddening(AKs).resample(filtLp.wave) # Convert luminosity to erg/s L_all = 10**(logL) * c.Lsun # luminsoity in erg/s # Calculate radius R_all = np.sqrt(L_all / (4.0 * math.pi * c.sigma * temp**4)) R_all /= (c.cm_in_AU * c.AU_in_pc) # For each temperature extract the synthetic photometry. for ii in range(len(temp)): gravity = logg[ii] L = L_all[ii] # in erg/s T = temp[ii] # in Kelvin R = R_all[ii] # in pc # Get the atmosphere model now. Wavelength is in Angstroms star = atm.get_merged_atmosphere(temperature=T, gravity=gravity) # Trim wavelength range down to JHKL range (0.5 - 4.25 microns) star = spectrum.trimSpectrum(star, 5000, 42500) # Convert into flux observed at Earth (unreddened) star *= (R / distance)**2 # in erg s^-1 cm^-2 A^-1 # ---------- # Now to the filter integrations # ---------- mag127m[ii] = mag_in_filter(star, filt127m, red127m) mag139m[ii] = mag_in_filter(star, filt139m, red139m) mag153m[ii] = mag_in_filter(star, filt153m, red153m) magH[ii] = mag_in_filter(star, filtH, redH) magKp[ii] = mag_in_filter(star, filtKp, redKp) magLp[ii] = mag_in_filter(star, filtLp, redLp) if verbose: print 'M = %7.3f Msun T = %5d K R = %2.1f Rsun logg = %4.2f F127M = %4.2f F139M = %4.2f F153M = %4.2f' % \ (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii], mag127m[ii], mag139m[ii], mag153m[ii]) iso = objects.DataHolder() iso.M = mass iso.T = temp iso.logg = logg iso.logL = logL iso.mag127m = mag127m iso.mag139m = mag139m iso.mag153m = mag153m iso.magH = magH iso.magKp = magKp iso.magLp = magLp iso.isWR = isWR _out = open(outFile, 'wb') pickle.dump(mass, _out) pickle.dump(temp, _out) pickle.dump(logg, _out) pickle.dump(logL, _out) pickle.dump(mag127m, _out) pickle.dump(mag139m, _out) pickle.dump(mag153m, _out) pickle.dump(magH, _out) pickle.dump(magKp, _out) pickle.dump(magLp, _out) pickle.dump(isWR, _out) _out.close() endTime = time.time() print ' Time taken: %d seconds' % (endTime - startTime)