def get_fdnu(df): asf = asfgrid.Seism() evstate = np.ones(len(df)) * 2 logz = np.log10(df.Z.values) teff = df.Teff.values + args.tempdiff dnu = df.dnu.values numax = df.numax.values mass, radius = asf.get_mass_radius(evstate, logz, teff, dnu, numax) logg = asf.mr2logg(mass, radius) fdnu = asf._get_fdnu(evstate, logz, teff, mass, logg, fill_value='nearest') return fdnu
def stparas(input, dnumodel=0, bcmodel=0, dustmodel=0, dnucor=0, useav=0, plot=0): # IAU XXIX Resolution, Mamajek et al. (2015) r_sun = 6.957e10 gconst = 6.67408e-8 gm = 1.3271244e26 m_sun = gm / gconst rho_sun = m_sun / (4. / 3. * np.pi * r_sun**3) g_sun = gconst * m_sun / r_sun**2. # solar constants numaxsun = 3090. dnusun = 135.1 teffsun = 5777. Msun = 4.74 # NB this is fixed to MESA BCs! # assumed uncertainty in bolometric corrections err_bc = 0.02 # assumed uncertainty in extinction err_ext = 0.02 # load model if they're not passed on if (dnumodel == 0): dnumodel = asfgrid.Seism() if (bcmodel == 0): bcmodel = h5py.File('bcgrid.h5', 'r') if (dustmodel == 0.): dustmodel = mwdust.Green15() # object containing output values out = resdata() ## extinction coefficients extfactors = extinction() ######################################################################################## # case 1: input is parallax + colors ######################################################################################## if ((input.plx > 0.)): # only K-band for now teffgrid = np.array(bcmodel['teffgrid']) avgrid = np.array(bcmodel['avgrid']) interp = RegularGridInterpolator((np.array(bcmodel['teffgrid']),\ np.array(bcmodel['logggrid']),np.array(bcmodel['fehgrid']),\ np.array(bcmodel['avgrid'])),np.array(bcmodel['bc_k'])) ### Monte Carlo starts here # number of samples nsample = 1e5 # length scale for exp decreasing vol density prior in pc L = 1350. # get a rough maximum distance tempdis = 1. / input.plx tempdise = input.plxe / input.plx**2 maxds = tempdis + 5. * tempdise ds = np.arange(1., 10000, 1.) lh = np.exp((-1. / (2. * input.plxe**2)) * (input.plx - 1. / ds)**2) prior = (ds**2 / (2. * L**3.)) * np.exp(-ds / L) dis = lh * prior dis2 = dis / np.sum(dis) norm = dis2 / np.max(dis2) um = np.where((ds > tempdis) & (norm < 0.001))[0] if (len(um) > 0): maxds = np.min(ds[um]) else: maxds = 10000. print 'using max distance:', maxds ds = np.linspace(1., maxds, 10000) lh = (1./(np.sqrt(2.*np.pi)*input.plxe))*\ np.exp( (-1./(2.*input.plxe**2))*(input.plx-1./ds)**2) prior = (ds**2 / (2. * L**3.)) * np.exp(-ds / L) prior = np.zeros(len(lh)) + 1. dis = lh * prior dis2 = dis / np.sum(dis) # sample distances following the discrete distance posterior np.random.seed(seed=10) dsamp = np.random.choice(ds, p=dis2, size=nsample) equ = ephem.Equatorial(input.ra * np.pi / 180., input.dec * np.pi / 180., epoch=ephem.J2000) gal = ephem.Galactic(equ) lon_deg = gal.lon * 180. / np.pi lat_deg = gal.lat * 180. / np.pi avs = 3.1 * dustmodel(lon_deg, lat_deg, dsamp / 1000.) # NB the next line means that useav is not actually working yet # avs = np.zeros(len(dsamp))+useav ext = avs * extfactors.ak ext = 0. # already in BC if (input.teff == -99.): teff = casagrande(jkmag, 0.0) teffe = 100. else: teff = input.teff teffe = input.teffe np.random.seed(seed=11) teffsamp = teff + np.random.randn(nsample) * teffe map = input.kmag mape = input.kmage np.random.seed(seed=12) map_samp = map + np.random.randn(nsample) * mape absmag = -5. * np.log10(dsamp) - ext + map_samp + 5. if (input.teff < np.min(teffgrid)): return out if (input.teff > np.max(teffgrid)): return out #if (out.av > np.max(avgrid)): # return out #if (out.av < np.min(avgrid)): # return out if ((input.teff > -99.) & (input.logg > -99.) & (input.feh > -99.)): #bc = interp(np.array([input.teff,input.logg,input.feh,0.]))[0] arr = np.zeros((len(avs), 4)) arr[:, 0] = np.zeros(len(avs)) + input.teff arr[:, 1] = np.zeros(len(avs)) + input.logg arr[:, 2] = np.zeros(len(avs)) + input.feh arr[:, 3] = np.zeros(len(avs)) + avs um = np.where(arr[:, 3] < 0.)[0] arr[um, 3] = 0. #pdb.set_trace() bc = interp(arr) #pdb.set_trace() #pdb.set_trace() Mvbol = absmag + bc lum = 10**((Mvbol - Msun) / (-2.5)) t = teffsamp / teffsun rad = (lum * t**(-4.))**0.5 #pdb.set_trace() out.teff = input.teff out.teffe = input.teffe ''' out.lum=np.median(lum) out.lumep=np.percentile(lum,84.1)-out.lum out.lumem=out.lum-np.percentile(lum,15.9) out.rad=np.median(rad) out.radep=np.percentile(rad,84.1)-out.rad out.radem=out.rad-np.percentile(rad,15.9) out.dis=np.median(dsamp) out.disep=np.percentile(dsamp,84.1)-out.dis out.disem=out.dis-np.percentile(dsamp,15.9) ''' out.avs = np.median(avs) out.avsep = np.percentile(avs, 84.1) - out.avs out.avsem = out.avs - np.percentile(avs, 15.9) #pdb.set_trace() out.rad, out.radep, out.radem, radbn = getstat(rad) out.lum, out.lumep, out.lumem, lumbn = getstat(lum) out.dis, out.disep, out.disem, disbn = getstat(dsamp) #out.avs,out.avsep,out.avsem=getstat(avs) #pdb.set_trace() out.teff = input.teff out.teffep = input.teffe out.teffem = input.teffe out.logg = input.logg out.loggep = input.logge out.loggem = input.logge out.feh = input.feh out.fehep = input.fehe out.fehem = input.fehe if (plot == 1): plt.ion() plt.clf() plt.subplot(3, 2, 1) plt.hist(teffsamp, bins=100) plt.title('Teff') plt.subplot(3, 2, 2) plt.hist(lum, bins=lumbn) plt.title('Lum') plt.subplot(3, 2, 3) plt.hist(rad, bins=radbn) plt.title('Rad') plt.subplot(3, 2, 4) plt.hist(absmag, bins=100) plt.title('absmag') plt.subplot(3, 2, 5) plt.hist(dsamp, bins=disbn) plt.title('distance') plt.subplot(3, 2, 6) plt.hist(avs, bins=100) plt.title('Av') #pdb.set_trace() print ' ' print 'teff(K):', out.teff, '+/-', out.teffe print 'dis(pc):', out.dis, '+', out.disep, '-', out.disem print 'av(mag):', out.avs, '+', out.avsep, '-', out.avsem print 'rad(rsun):', out.rad, '+', out.radep, '-', out.radem print 'lum(lsun):', out.lum, '+', out.lumep, '-', out.lumem print '-----' #raw_input(':') #pdb.set_trace() ######################################################################################## # case 1: input is spectroscopy + seismology ######################################################################################## if ((input.dnu > -99.) & (input.teff > -99.)): # seismic logg, density, M and R from scaling relations; this is iterated, # since Dnu scaling relation correction depends on M dmass = 1. fdnu = 1. dnuo = input.dnu oldmass = 1.0 nit = 0. while (nit < 5): numaxn = input.numax / numaxsun numaxne = input.numaxe / numaxsun dnun = (dnuo / fdnu) / dnusun dnune = input.dnue / dnusun teffn = input.teff / teffsun teffne = input.teffe / teffsun out.rad = (numaxn) * (dnun)**(-2.) * np.sqrt(teffn) out.rade = np.sqrt( (input.numaxe/input.numax)**2. + \ 4.*(input.dnue/input.dnu)**2. + \ 0.25*(input.teffe/input.teff)**2.)*out.rad out.mass = out.rad**3. * (dnun)**2. out.masse = np.sqrt( 9.*(out.rade/out.rad)**2. + \ 4.*(input.dnue/input.dnu)**2. )*out.mass out.rho = rho_sun * (dnun**2.) out.rhoe = np.sqrt(4. * (input.dnue / input.dnu)**2.) * out.rho g = g_sun * numaxn * teffn**0.5 ge = np.sqrt ( (input.numaxe/input.numax)**2. + \ (0.5*input.teffe/input.teff)**2. ) * g out.logg = np.log10(g) out.logge = ge / (g * np.log(10.)) # Dnu scaling relation correction from Sharma et al. 2016 if (dnucor == 1): if (input.clump == 1): evstate = 2 else: evstate = 1 #pdb.set_trace() dnu, numax, fdnu = dnumodel.get_dnu_numax(evstate, input.feh, input.teff, out.mass, out.mass, out.logg, isfeh=True) #print out.mass,fdnu dmass = abs((oldmass - out.mass) / out.mass) oldmass = out.mass nit = nit + 1 print fdnu #pdb.set_trace() out.lum = out.rad**2. * teffn**4. out.lume = np.sqrt((2. * out.rade / out.rad)**2. + (4. * input.teffe / input.teff)**2.) * out.lum print ' ' print 'teff(K):', input.teff, '+/-', input.teffe print 'feh(dex):', input.feh, '+/-', input.fehe print 'logg(dex):', out.logg, '+/-', out.logge print 'rho(cgs):', out.rho, '+/-', out.rhoe print 'rad(rsun):', out.rad, '+/-', out.rade print 'mass(msun):', out.mass, '+/-', out.masse print 'lum(lsun):', out.lum, '+/-', out.lume print '-----' out.teff = input.teff out.teffep = input.teffe out.teffem = input.teffe out.feh = input.feh out.fehep = input.fehe out.fehem = input.fehe out.loggep = out.logge out.loggem = out.logge out.radep = out.rade out.radem = out.rade out.rhoep = out.rhoe out.rhoem = out.rhoe out.massep = out.masse out.massem = out.masse out.lumep = out.lume out.lumem = out.lume ddis = 1. ext = 0.0 err_ = 0.01 olddis = 100.0 # pick an apparent magnitude from input map = -99. if (input.vmag > -99.): map = input.vmag mape = input.vmage str = 'bc_v' avtoext = extfactors.av if (input.vtmag > -99.): map = input.vtmag mape = input.vtmage str = 'bc_vt' avtoext = extfactors.avt if (input.jmag > -99.): map = input.jmag mape = input.jmage str = 'bc_j' avtoext = extfactors.aj if (input.kmag > -99.): map = input.kmag mape = input.kmage str = 'bc_k' avtoext = extfactors.ak if (input.gamag > -99.): map = input.gamag mape = input.gamage str = 'bc_ga' avtoext = extfactors.aga # if apparent mag is given, calculate distance if (map > -99.): print 'using ' + str print 'using coords: ', input.ra, input.dec equ = ephem.Equatorial(input.ra * np.pi / 180., input.dec * np.pi / 180., epoch=ephem.J2000) gal = ephem.Galactic(equ) lon_deg = gal.lon * 180. / np.pi lat_deg = gal.lat * 180. / np.pi # iterated since BC depends on extinction nit = 0 while (nit < 5): if (nit == 0.): out.avs = 0.0 else: out.avs = 3.1 * dustmodel(lon_deg, lat_deg, out.dis / 1000.)[0] #print lon_deg,lat_deg,out.dis if (useav != 0.): out.avs = useav if (out.avs < 0.): out.avs = 0.0 ext = out.avs * avtoext # bolometric correction interpolated from MESA interp = RegularGridInterpolator((np.array(bcmodel['teffgrid']),\ np.array(bcmodel['logggrid']),np.array(bcmodel['fehgrid']),\ np.array(bcmodel['avgrid'])),np.array(bcmodel[str])) #pdb.set_trace() bc = interp( np.array([input.teff, out.logg, input.feh, out.avs]))[0] #bc = interp(np.array([input.teff,out.logg,input.feh,0.]))[0] Mvbol = -2.5 * (np.log10(out.lum)) + Msun Mvbole = np.sqrt( (-2.5 / (out.lum * np.log(10.)))**2 * out.lume**2) Mabs = Mvbol - bc Mabse = np.sqrt(Mvbole**2 + err_bc**2) ext = 0. # ext already applied in BC logplx = (Mabs - 5. - map + ext) / 5. logplxe = np.sqrt((Mabse / 5.)**2. + (mape / 5.)**2. + (err_ext / 5.)**2.) out.plx = 10.**logplx out.plxe = np.log(10) * 10.**logplx * logplxe out.dis = 1. / out.plx out.dise = out.plxe / out.plx**2. ddis = abs((olddis - out.dis) / out.dis) #print olddis,out.dis,ddis,ext olddis = out.dis nit = nit + 1 #print out.dis,out.avs #pdb.set_trace() print 'Av(mag):', out.avs print 'plx(mas):', out.plx * 1e3, '+/-', out.plxe * 1e3 print 'dis(pc):', out.dis, '+/-', out.dise out.disep = out.dise out.disem = out.dise out.mabs = Mabs return out
import sys import ebf import numpy as np import scipy.interpolate import pdb import asfgrid from astropy.io import ascii from classify_direct import * dnumodel = asfgrid.Seism() bcmodel = h5py.File('bcgrid.h5', 'r') dustmodel = mwdust.Combined15() x=obsdata() # example: HIP84970 x.addcoords(260.50241395,-24.99954638) x.addmag([3.26],[0.01]) # magnitude for distance modulus; needs to be consistent with band keyword x.addbv([3.03,3.26],[0.01,0.01]) x.addplx(7.48/1e3,0.17/1e3) paras=stparas(input=x,bcmodel=bcmodel,dustmodel=dustmodel,\ useav=-99.,plot=1,band='v') #raw_input(':') #x.addspec([5065.,-99.0,-0.1],[120.,0.0,0.2]) #x.addseismo([231.,16.5],[10.,0.5])