def make_lookback_axis3(ax, cosmo, max_redshift): ax2 = ax.twiny() minor_tick_labels = np.arange(0, 13, 2) major_tick_labels = np.arange(1, 13, 2) major_tick_loc = np.zeros(len(major_tick_labels)) minor_tick_loc = np.zeros(len(minor_tick_labels)) for idx, labels in enumerate(zip(major_tick_labels, minor_tick_labels)): major, minor = labels if major < 0.0001: major_tick_loc[idx] = 0 else: major_tick_loc[idx] = cosmology.z_at_value(cosmo.lookback_time, apu.Gyr * major) / max_redshift if minor < 0.0001: minor_tick_loc[idx] = 0 else: minor_tick_loc[idx] = cosmology.z_at_value(cosmo.lookback_time, apu.Gyr * minor) / max_redshift ax2.set_xticks(major_tick_loc) ax2.set_xticks(minor_tick_loc, minor=True) major_tick_labels = [f"$\mathrm{x:.0f}$" for x in major_tick_labels] ax2.set_xticklabels(major_tick_labels, fontsize=14) return ax2
def minimum(self, minimum): cosmology = get_cosmology(self.cosmology) self._minimum[self.name] = minimum if self.name == 'redshift': self._minimum['luminosity_distance'] =\ cosmology.luminosity_distance(minimum).value self._minimum['comoving_distance'] =\ cosmology.comoving_distance(minimum).value elif self.name == 'luminosity_distance': if minimum == 0: self._minimum['redshift'] = 0 else: self._minimum['redshift'] = cosmo.z_at_value( cosmology.luminosity_distance, minimum * self.unit) self._minimum['comoving_distance'] = self._minimum['redshift'] elif self.name == 'comoving_distance': if minimum == 0: self._minimum['redshift'] = 0 else: self._minimum['redshift'] = cosmo.z_at_value( cosmology.comoving_distance, minimum * self.unit) self._minimum['luminosity_distance'] = self._minimum['redshift'] try: self._update_instance() except (AttributeError, KeyError): pass
def SIGMA_CRIT(DS, DL): # Critical surface density for lens at distance DL and source at distance DS zS = cosmology.z_at_value(cosmology.Planck15.angular_diameter_distance, DS, zmax=1.1) zL = cosmology.z_at_value(cosmology.Planck15.angular_diameter_distance, DL, zmax=1.1) DSL = cosmology.Planck15.angular_diameter_distance_z1z2(zL, zS) return c**2 / (4 * np.pi * G) * (DS / (DSL * DL))
def slice_z_cosmo(slice, z, radius): """Slices in redshift considering a distance to cut""" zmax = z_at_value(cosmo.comoving_distance, cosmo.comoving_distance(z) + radius) zmin = z_at_value(cosmo.comoving_distance, cosmo.comoving_distance(z) - radius) print zmin - zmax slice = slice[np.where(slice["zb_1"] < zmax)] slice = slice[np.where(slice["zb_1"] > zmin)] return slice
def cMpc_to_z(cMpc, cosmology="Planck15"): """ Convert a comoving distance with units Mpc into a redshift. Parameters ---------- cMpc: array-like, shape (N, ) The distance values. Must be 1D or scalar. cosmology: string or astropy.cosmology.core.FLRW The cosmology used to calculate distance. This can either be a string of the cosmology keyword used in astropy (e.g 'Planck13' or 'WMAP7') or an instance of an astropy.cosmology. Default: 'Planck15' Returns ------- redshift: astropy.unit.Quantity The distance to a redshift in comoving Mpc. Examples -------- """ cosmo = get_cosmology_from_name(cosmology) # If the array doesn't have units, apply them for calculation later. if not isinstance(cMpc, apu.Quantity): cMpc = cMpc * apu.Mpc # If the comoving distance is really small the user likely wants the # result to be at 0.0 redshift. 1e-4 Mpc is approx 100 pc. distance_zero_threshold = 1e-4 * apu.Mpc # Check of the input distances is a list or a scalar. distance_is_scalar = cMpc.isscalar # If the distance is a scalar, perform a scalar calculation. if distance_is_scalar: if cMpc >= distance_zero_threshold: redshift = acosmo.z_at_value(cosmo.comoving_distance, cMpc) else: redshift = 0.0 # If the distance is an array, perform array calculation else: # Default value is 0.0 redshift redshift = np.zeros_like(cMpc.value) for i, dist in enumerate(cMpc): if dist >= distance_zero_threshold: redshift[i] = acosmo.z_at_value(cosmo.comoving_distance, dist) return redshift
def compute_zmax(l, z, cosmo, flux_limit, zspacing=0.1, jack_version=False, output=True): """Return the maximum z such that the object's flux would be above the limit.""" import astropy.units as u if jack_version is False: from astropy.cosmology import z_at_value def func(lum): return (np.sqrt(lum / (4 * np.pi * flux_limit)) * u.cm).to(u.Mpc) zmin = z_at_value(cosmo.luminosity_distance, func(l.min()), zmin=1e-16, zmax=8) zmax = z_at_value(cosmo.luminosity_distance, func(l.max()), zmax=50) zgrid = np.logspace(np.log10(zmin), np.log10(zmax), 50) lgrid = cosmo.luminosity_distance(zgrid) zmaxes = np.interp(func(l).value, lgrid.value, zgrid) if np.any(zmaxes < z) and output is True: print("bad zmax inference", np.sum(zmaxes < z)) print("this is probably due to an issue with the flux limit") print("zmax/zmin will default to zbin range") return zmaxes zmaxes = [] zspacing_orig = zspacing for ll, zz in zip(l, z): diff = 0.1 ztrial = zz fine = False zspacing = zspacing_orig while diff > 0: ztrial += zspacing diff = ll / (4 * np.pi * cosmo.luminosity_distance(ztrial).to( u.cm).value**2) - flux_limit if diff < 0 and fine is False: fine = True diff = 0.1 ztrial -= zspacing zspacing /= 10 zmaxes.append(ztrial) return np.array(zmaxes)
def rsSFR(m_star, Time): if Time.size == 1: z = z_at_value(cosmo.age, Time) else: z = np.array([z_at_value(cosmo.age, t) for t in Time]) rsSFR_1 = 0.07 * (m_star / 10**10.5)**(-0.1) * (1. + z)**3. rsSFR_2 = 0.3 * (m_star / 10**10.5)**(-0.1) * (1. + z)**(5 / 3.) rsSFR = np.concatenate((rsSFR_2[z > 2], rsSFR_1[z < 2])) if rsSFR.size == 1: return rsSFR[0] * (1. / u.Gyr) else: return rsSFR * (1. / u.Gyr)
def _set_limit(self, value, limit_dict, recalculate_array=False): """ Set either of the limits for redshift, luminosity, and comoving distances Parameters ---------- value: float Limit value in current class' parameter limit_dict: dict The limit dictionary to modify in place recalculate_array: boolean Determines if the distance arrays are recalculated """ cosmology = get_cosmology(self.cosmology) limit_dict[self.name] = value if self.name == 'redshift': limit_dict['luminosity_distance'] = \ cosmology.luminosity_distance(value).value limit_dict['comoving_distance'] = \ cosmology.comoving_distance(value).value elif self.name == 'luminosity_distance': if value == 0: limit_dict['redshift'] = 0 else: limit_dict['redshift'] = cosmo.z_at_value( cosmology.luminosity_distance, value * self.unit) limit_dict['comoving_distance'] = ( cosmology.comoving_distance(limit_dict['redshift']).value ) elif self.name == 'comoving_distance': if value == 0: limit_dict['redshift'] = 0 else: limit_dict['redshift'] = cosmo.z_at_value( cosmology.comoving_distance, value * self.unit) limit_dict['luminosity_distance'] = ( cosmology.luminosity_distance(limit_dict['redshift']).value ) if recalculate_array: if self.name == 'redshift': self.xx, self.yy = self._get_redshift_arrays() elif self.name == 'comoving_distance': self.xx, self.yy = self._get_comoving_distance_arrays() elif self.name == 'luminosity_distance': self.xx, self.yy = self._get_luminosity_distance_arrays() try: self._update_instance() except (AttributeError, KeyError): pass
def time_to_z(age, cosmology=None, v=False): """ returns the redshift of a given age using an astropy cosmology age is taken to be in Gyr if they're all less than 15, years otherwise (unless it's passed in as a YTQuantity/YTArray, then it's figured out) """ from yt import YTArray, YTQuantity if cosmology is None: from astropy.cosmology import Planck13 as cosmology from astropy.cosmology import z_at_value import astropy.units as u import numpy as np gyrconv = False #numpy array? if type(age) == type(np.array([1, 2, 3])): if (age < 15).all(): gyrconv = True age = u.Quantity(age * 1e9, u.yr) else: age = u.Quantity(age, u.yr) #single number? elif type(age) == type(1.2) or type(age) == type(1): if age < 15: gyrconv = True age = u.Quantity(age * 1e9, u.yr) else: age = u.Quantity(age, u.yr) #yt quantity? convert it elif type(age) == type(YTQuantity(12e9, 'yr')) or type(age) == type( YTArray([1., 2.])): age = u.Quantity(age.in_units('yr'), u.yr) #otherwise, gotta by an astropy quantity already else: assert type(age) == type(u.Quantity(13.6, u.yr)) if v and gyrconv: print "Converted to Gyr" try: it = iter(age) z = [] for ii in it: z.append(z_at_value(cosmology.age, ii)) z = np.array(z) except TypeError, te: # age is not iterable z = z_at_value(cosmology.age, age)
def pfiles(self): #Compute comoving distance to maximum redshift for each model d = list() for model in self.batch.models: d.append(model.cosmology.comoving_distance(self.zmax)) #Compute lens spacings d = np.array([dv.value for dv in d]) * d[0].unit #We want to make sure there are lenses up to the maximum of these distances lens_distances = np.arange(self.lens_thickness_Mpc,d.max().to(u.Mpc).value + self.lens_thickness_Mpc,self.lens_thickness_Mpc) * u.Mpc for model in self.batch.models: #Compute the redshifts of the Gadget snapshots z = np.zeros_like(lens_distances.value) for n,dlens in enumerate(lens_distances): z[n] = z_at_value(model.cosmology.comoving_distance,dlens) #Assgn values to gadget settings self.gadget2.OutputScaleFactor = np.sort(1/(1+z)) #Write parameter files collection = model["c0"] #Convert camb power spectra into ngenic ones collection.camb2ngenic(z=0.0,input_root=self.camb_lin_fileroot) #NGenIC and Gadget2 parameter files r = collection["r0"] r.writeNGenIC(self.ngenic) r.writeGadget2(self.gadget2)
def comoving_bins(z_min, z_max, n_bins): """Create bins equally spaced in comoving distance. Assumes a Planck2015 cosmology. Parameters ---------- z_min : `float` Minimum redshift. z_max : `float` Maximum redshift n_bins : `int` Number of redshift bins to create Returns ------- bin_edges : `numpy.ndarray`, (n_bins + 1,) Redshift bin edges. """ cov_min = Planck15.comoving_distance(z_min).value cov_max = Planck15.comoving_distance(z_max).value cov_edges = np.linspace(cov_min, cov_max, n_bins + 1) tmp_edges = [] for cov_edge in cov_edges: tmp_edges.append( z_at_value(Planck15.comoving_distance, cov_edge * u.Mpc)) return np.array(tmp_edges)
def inva(t): if t <= t_eq: a = sqrt(2 * sqrt(cosmo.Onu0+cosmo.Ogamma0) * (cosmo.H0 * t).decompose()).value else: z = z_at_value(cosmo.age, t*u.s, zmax=1e4) a = cosmo.scale_factor(z) return 1 / a
def test_gaussian_box_pyramid(): """ Gaussian box estimated using pyramid method. """ N = 256 #Vox per side L = 300. #Mpc sig = 2.0 mu = 0.0 box = np.random.normal(mu, sig, (N, N, N)) ## Unconventional approach, but start with equal distances and go to redshifts r0 = WMAP9.comoving_distance(6.0).to("Mpc").value r_mpc = np.linspace(r0, r0 + L, N) def comov_dist(z): return WMAP9.comoving_distance(z).to("Mpc").value Z = np.array([z_at_value(comov_dist, r, zmin=5.0) for r in r_mpc]) angular_extent = 300 / np.mean(r_mpc) # 300 Mpc box at this distance (kbins, pk), dV = pspec_funcs.box_pyramid_pspec(box, angular_extent, r_mpc, Z, cosmo=True, return_dV=True) import pylab as pl pl.plot(kbins, pk) print np.sqrt(np.var(dV)) pl.axhline(y=sig**2 * np.mean(dV)) pl.show()
def init(chain_index=None): if args.cosmo_prior: Hp = Planck15.H0.to(u.km / u.s / u.Mpc).value * Planck15.efunc( true_params['z_p']) * (1 + 0.01 * randn()) Om = Planck15.Om0 * (1 + 0.01 * randn()) else: Hp = Planck15.H0.to(u.km / u.s / u.Mpc).value * Planck15.efunc( true_params['z_p']) * (1 + 0.1 * randn()) Om = Planck15.Om0 * (1 + 0.1 * randn()) w = -1 + 0.1 * randn() c = cosmo.FlatwCDM(Hp / Planck15.efunc(true_params['z_p']), Om, w) MMax_d_p = (45 + 5 * randn()) * (1 + cosmo.z_at_value( c.luminosity_distance, Planck15.luminosity_distance(true_params['z_p']).to(u.Gpc))) smooth_max = 0.1 + 0.01 * randn() MMax_d_p_2sigma = exp(log(MMax_d_p) + 2 * smooth_max) alpha = 0.7 + 0.1 * randn() beta = 0.1 * randn() gamma = 3 + 0.1 * randn() return { 'H_p': Hp, 'Om': Om, 'w0': w, 'MMax_d_p': MMax_d_p, 'MMax_d_p_2sigma': MMax_d_p_2sigma, 'alpha': alpha, 'beta': beta, 'gamma': gamma, 'xs': randn(nobs, 3) }
def SNIa_position(i, indx, SNIa_num, dist_sr, u_lenspos, l_lenspos, fov_Mpc, S_ID, S_possky): sid = np.zeros(int(np.sum(SNIa_num))) sred = np.zeros(int(np.sum(SNIa_num))) sx = np.zeros(int(np.sum(SNIa_num))) sy = np.zeros(int(np.sum(SNIa_num))) sz = np.zeros(int(np.sum(SNIa_num))) indxtot = 0 # Iterate over Volume for y in indx[0]: [dist_min, dist_max] = [dist_sr[y], dist_sr[y+1]] # Iterate over Supernovae for x in range(int(SNIa_num[y])): # Generate random SNeIa location within a cone # with apex-angle thetaE_inf along the l.o.s. radial_rnd = u_lenspos*(l_lenspos + \ rnd.random()*(dist_max - l_lenspos)) # [Mpc] sposx = np.sqrt(radial_rnd[0]**2 + radial_rnd[1]**2 + radial_rnd[2]**2)#[Mpc] zs = z_at_value(cosmo.comoving_distance, sposx*u.Mpc, zmax=2) # max. distance equa to re charge = 1 if rnd.random() < 0.5 else -1 sposy = charge*rnd.random()*fov_Mpc[y]*0.5 #[Mpc] charge = 1 if rnd.random() < 0.5 else -1 sposz = charge*rnd.random()*fov_Mpc[y]*0.5 #[Mpc] # Write glafic file sid[indxtot] = i sred[indxtot] = zs sx[indxtot] = sposx sy[indxtot] = sposy sz[indxtot] = sposz indxtot = indxtot + 1; spossky = np.stack((sx, sy, sz)).transpose() return sid, sred, spossky
def process(self, **kwargs): """Process module.""" # If this parameter is not free and is already set, then skip if self._name in kwargs: return {} if self._value is None: self._lum_dist = kwargs.get(self.key('lumdist'), self._lum_dist) if self._value is None and self._lum_dist is not None: if self._lum_dist < 1.0: if not self._warned_small: self._printer.message('small_lumdist', [ str(np.around(self._lum_dist * 1.0e6, decimals=2)) ], warning=True) self._warned_small = True value = 0.0 else: value = z_at_value(cosmo.luminosity_distance, self._lum_dist * un.Mpc) else: value = self.value(kwargs['fraction']) else: value = self._value return {self._name: value}
def bin_histories(self, shid, binLimits, binWidths): """ Bin star formation histories from particle age data Args: binning (str) linear or log name (str) linear or log Nbins (int) number of bins Nlow (float) if log binning chosen, the log age of the second lower bin limit """ ftime,met,imass = self.load_galaxy(shid) # Add redshift to give age of stars from point of observation binLimits_temp = binLimits + self.cosmo.lookback_time(self.redshift).value # first set age limits so that z calculation doesn't fail binLimits_temp[binLimits_temp < 1e-6] = 1e-6 binLimits_temp[binLimits_temp > (self.cosmo.age(0).value - 1e-3)] = (self.cosmo.age(0).value - 1e-3) # convert binLimits to scale factor binLimits_temp = self.cosmo.scale_factor([z_at_value(self.cosmo.lookback_time, a) for a in binLimits_temp * u.Gyr]) # weights converts age to SFR (bins must increase monotonically, so reverse for now) counts, dummy = np.histogram(ftime, bins=binLimits_temp[::-1], weights=imass); ## divide by bin width in (Giga)years to give SFR in Msol / year # (reverse counts to fit original) return counts[::-1] / binWidths
def i_prob_Illustris_ecc(Mstar, Mtot, q, e_0, nq_interp, min_freq): """ Probability that this galaxy contains a binary in the PTA band """ chirpMass = mchirp_q(q, Mtot) / s_mass #in solar mass units M1 = Mtot / (1 + q) M2 = M1 * q mu_min, mu_max = 0.25, 1.0 gamma = 1.0 # for Hernquist profile, see Dehen 1993 H = 15 #Mstar = Mstar*MzMnow(mu, sigma) # scale M* according to Figure 7 of de Lucia and Blaizot 2007 MstarZ = 0.7 * Mstar hardening_t, r_inf_here = t_hard_ecc(MstarZ, q, gamma, Mtot, e_0) friction_t = tfric(MstarZ, M2) timescale = hardening_t + friction_t # Gyrs # if timescale > 12.25 Gyrs (z=4), no merging SMBHs # also limit of validity for Rodriguez-Gomez + (2015) fit in Table 1. if timescale > 12.25: return 0, 'nan', timescale * 1e9, 'nan', 'nan', r_inf_here, friction_t, hardening_t else: z = z_at_value(Planck15.age, (13.79 - timescale) * u.Gyr) # redshift of progenitor galaxies a_hard_ecc = a_StarGW_ecc(MstarZ, q, Mtot, gamma, H, e_0) t2c = time_to_c_ecc(e_0, a_hard_ecc, q, Mtot, nq_interp, min_freq) # in years mergRate = cumulative_merg_ill(mu_min, mu_max, MstarZ, z) # rate per Gigayear Tz = timescale * 1e9 ans = t2c * mergRate / 1e9 return ans, z, Tz, mergRate, t2c, r_inf_here, friction_t, hardening_t
def _z_fog_corr(self, dcfogcorr, abs_mag, halos, galinhalo, mag_threshold=-20.5): """Corrected redshift.""" # array to store return results zfogcorr = np.zeros(len(self.z)) # run for each massive halo for i in halos.labels_h_massive[0]: # select only galaxies with magnitudes over than -20.5 sat_gal_mask = (galinhalo.groups == i) * (abs_mag > mag_threshold) # number of galaxies for corrections numgal = np.sum(sat_gal_mask) z_galaxies = np.zeros(numgal) dc_galaxies = dcfogcorr[sat_gal_mask] redshift = self.z[sat_gal_mask] # corrected redshift of each galaxy # run for each galaxy for j in range(numgal): z_galaxies[j] = z_at_value( self.cosmo.comoving_distance, dc_galaxies[j] * u.Mpc, zmin=redshift.min() - 0.01, zmax=redshift.max() + 0.01, ) zfogcorr[sat_gal_mask] = z_galaxies return zfogcorr
def i_prob_Illustris_gasM30(Mstar, Mtot, q, min_freq): """ Probability that this galaxy contains a binary in the PTA band """ chirpMass = mchirp_q(q, Mtot) / s_mass #in solar mass units M1 = Mtot / (1 + q) M2 = M1 * q mu_min, mu_max = 0.25, 1.0 gamma = 1.0 # for Hernquist profile, see Dehen 1993 #Mstar = Mstar*MzMnow(mu, sigma) # scale M* according to Figure 7 of de Lucia and Blaizot 2007 MstarZ = 0.7 * Mstar a_sh_gas = a_SHGas(MstarZ, gamma, Mtot) t_sh_gas = t_SHGas(Mtot, a_sh_gas) a_gas_GW = a_gas_M30(q, Mtot) t_gas_GW = t_gas_M30(Mtot, a_gas_GW) friction_t = tfric(MstarZ, M2) timescale = t_sh_gas + t_gas_GW + friction_t # Gyrs # if timescale is longer than a Hubble time, 0 probability # also, if timescale > 12.25 Gyrs (z=4), no merging SMBHs # also limit of validity for Rodriguez-Gomez + fit in Table 1. if timescale > 12.25: return 0, 'nan', timescale * 1e9, 'nan', 'nan', friction_t, t_sh_gas, t_gas_GW else: z = z_at_value(Planck15.age, (13.79 - timescale) * u.Gyr) # redshift of progenitor galaxies #print "redshift is ", z t2c = time_to_c_wMc(chirpMass, min_freq) # in years mergRate = cumulative_merg_ill(mu_min, mu_max, MstarZ, z) # rate per Gigayear Tz = timescale * 1e9 ans = t2c * mergRate / 1e9 return ans, z, Tz, mergRate, t2c, friction_t, t_sh_gas, t_gas_GW
def time_to_z(age,cosmology=None,v=False): """ returns the redshift of a given age using an astropy cosmology age is taken to be in Gyr if they're all less than 15, years otherwise (unless it's passed in as a YTQuantity/YTArray, then it's figured out) """ from yt import YTArray,YTQuantity if cosmology is None: from astropy.cosmology import Planck13 as cosmology from astropy.cosmology import z_at_value import astropy.units as u import numpy as np gyrconv = False #numpy array? if type(age) == type(np.array([1,2,3])): if (age<15).all(): gyrconv = True age = u.Quantity(age*1e9,u.yr) else: age = u.Quantity(age,u.yr) #single number? elif type(age) == type(1.2) or type(age) == type(1): if age < 15: gyrconv = True age = u.Quantity(age*1e9,u.yr) else: age = u.Quantity(age,u.yr) #yt quantity? convert it elif type(age) == type(YTQuantity(12e9,'yr')) or type(age) == type(YTArray([1.,2.])): age = u.Quantity(age.in_units('yr'),u.yr) #otherwise, gotta by an astropy quantity already else: assert type(age) == type(u.Quantity(13.6,u.yr)) if v and gyrconv: print "Converted to Gyr" try: it = iter(age) z = [] for ii in it: z.append(z_at_value(cosmology.age,ii)) z = np.array(z) except TypeError, te: # age is not iterable z = z_at_value(cosmology.age,age)
def lightcone_redshifts(self): """Redshift of each cell along the redshift axis.""" return np.array( [ z_at_value(self.cosmo_params.cosmo.comoving_distance, d * units.Mpc) for d in self.lightcone_distances ] )
def set_redshift(self, zz=0.0): """ Method to change the redshift. """ if zz is None: self.redshift = apy_cosmo.z_at_value(cosmo.luminosity_distance, self.lumD*u.Mpc) else: self.redshift = zz
def cartesian_to_sky(x, y, z, cosmo=Planck15, return_redshift=True): from astropy.cosmology import z_at_value from astropy import units as u ra = np.arctan2(y, x) * 180.0 / np.pi dist = np.sqrt(x**2 + y**2 + z**2) dec = 90.0 - np.arccos(z / dist) / np.pi * 180. if return_redshift: try: redshift = z_at_value(cosmo.luminosity_distance, dist * u.Mpc) except: redshift = [ z_at_value(cosmo.luminosity_distance, dd) for dd in dist * u.Mpc ] return ra, dec, redshift else: return ra, dec
def gchi_to_nz(chi, gchi, cosmo=cosmology.Planck15, niter=3): from numpy import min, max, linspace, interp, gradient, apply_along_axis from astropy.cosmology import z_at_value chiu = cosmo.comoving_distance(0).unit zmin = z_at_value(cosmo.comoving_distance, min(chi) * chiu) zmax = z_at_value(cosmo.comoving_distance, max(chi) * chiu) zint = linspace(zmin, zmax, 10 * len(chi)) for i in range(niter): cint = cosmo.comoving_distance(zint).value zint = interp(chi, cint, zint) z = zint dz = gradient(z) dchi = gradient(chi) dif1 = apply_along_axis(gradient, -1, gchi) dif2 = apply_along_axis(gradient, -1, dif1 / dchi) nz = chi * dif2 / dz return z, nz
def setup_galaxy(self): self.sersic_index = 1.0 self.position_angle = np.random.uniform(0., np.pi) # radians self.redshift = z_at_value(cosmo.luminosity_distance, self.distance * u.Mpc) self.re_arcsec = self.re_kpc * cosmo.arcsec_per_kpc_proper( self.redshift).value self.re_pixels = self.re_arcsec / self.arcsec_per_pixel
def maximum(self, maximum): cosmology = get_cosmology(self.cosmology) self._maximum[self.name] = maximum if self.name == 'redshift': self._maximum['luminosity_distance'] = \ cosmology.luminosity_distance(maximum).value self._maximum['comoving_distance'] = \ cosmology.comoving_distance(maximum).value elif self.name == 'luminosity_distance': self._maximum['redshift'] = cosmo.z_at_value( cosmology.luminosity_distance, maximum * self.unit) self._maximum['comoving_distance'] = self._maximum['redshift'] elif self.name == 'comoving_distance': self._maximum['redshift'] = cosmo.z_at_value( cosmology.comoving_distance, maximum * self.unit) self._maximum['luminosity_distance'] = self._maximum['redshift'] if getattr(self._minimum, self.name, np.inf) < np.inf: self.__update_instance()
def set_redshift(self, zz=0.0): """ Method to change the redshift. """ if zz is None: self.redshift = apy_cosmo.z_at_value(cosmo.luminosity_distance, self.lumD * u.Mpc) else: self.redshift = zz
def JeansLength(self,z): """ Computes Jeans length in unitless Delta z lambda_J=2.3 Mpc (1+z)^-3/2 Pshirkov 2016 """ dist=Planck13.lookback_distance(z).value # in Mpc jeanslength=2.3*(1+z)**(-1.5) # in Mpc z1=z_at_value(Planck13.lookback_distance,(dist+jeanslength)*u.Mpc) return z1-z
def check_redshift(self): """ Force consistency between redshift, luminosity distance, central observed wavelength and angular diameter distance, superseding the values of each one of this variables following the hierarchical order previously presented. All estimates of these quantities are based on LambdaCDM cosmology. Returns ------- dl : astropy.units.core.Unit Luminosity distance where the galaxy is located in (Mpc) lambda_obs : astropy.units.core.Unit Central observed wavelength in (angstrom). dist_angular : astropy.units.core.Unit Angular diameter distance in (Mpc). """ if ~np.isnan(self.redshift): self.dl = cosmo.luminosity_distance(self.redshift) self.lambda_obs = (1 + self.redshift) * ct.Halpha0 self.dist_angular = cosmo.angular_diameter_distance(self.redshift) else: if ~np.isnan(self.dl): self.redshift = z_at_value(cosmo.luminosity_distance, self.dl) self.lambda_obs = (1 + self.redshift) * ct.Halpha0 self.dist_angular = cosmo.angular_diameter_distance( self.redshift) elif ~np.isnan(self.lambda_obs): self.redshift = (self.lambda_obs / ct.Halpha0) - 1 self.dl = cosmo.luminosity_distance(self.redshift) self.dist_angular = cosmo.angular_diameter_distance( self.redshift) # For the angular diameter distance there are multiple corresponding redshift # values for the LambdaCDM cosmology, so here we will choose the one that meets # the parameters established within the z_at_value module of astropy. elif ~np.isnan(self.dist_angular): self.redshift = z_at_value(cosmo.angular_diameter_distance, self.dist_angular) self.dl = cosmo.luminosity_distance(self.redshift) self.lambda_obs = (1 + self.redshift) * ct.Halpha0
def __init__(self, d_min=None, d_max=None, units='Mpc', cosmology='Planck15', scale=1000.0, pad=0.05, n_interp=500): self.units = u.Unit(units) try: self.cosmology = getattr(cosmo, cosmology) logger.info(f'Using cosmology: {cosmology}') except AttributeError: raise RuntimeError( f'Could not get specified cosmology ({cosmology}) from ' '`astropy.cosmology`. Available cosmologies are: ' f'{cosmo.parameters.available}. See astropy documentation ' 'for more details.') self.scale = np.float64(scale) self.pad = pad self.n_interp = n_interp self.dl_min = (1 - self.pad) * d_min self.dl_max = (1 + self.pad) * d_max logger.debug(f'Min and max distances: [{self.dl_min}, {self.dl_max}]') self.dc_min = self.cosmology.comoving_distance( cosmo.z_at_value(self.cosmology.luminosity_distance, self.dl_min * self.units)).value self.dc_max = self.cosmology.comoving_distance( cosmo.z_at_value(self.cosmology.luminosity_distance, self.dl_max * self.units)).value logger.debug('Making distance look up table') dc_array = np.linspace(self.dc_min, self.dc_max, self.n_interp) dl_array = self.cosmology.luminosity_distance([ cosmo.z_at_value(self.cosmology.comoving_distance, d * self.units) for d in dc_array ]).value self.interp_dc2dl = interpolate.splrep(dc_array, dl_array) self.interp_dl2dc = interpolate.splrep(dl_array, dc_array)
def toSky(cs): c1 = cs.T[0] c2 = cs.T[1] c3 = cs.T[2] r = np.sqrt(c1**2. + c2**2. + c3**2.) dec = np.arcsin(c3 / r) / D2R ra = np.arccos(c1 / np.sqrt(c1**2. + c2**2.)) / D2R zmn = z_at_value(Kos.comoving_distance, np.amin(r) * u.Mpc) zmx = z_at_value(Kos.comoving_distance, np.amax(r) * u.Mpc) zmn = zmn - (zstp + zmn % zstp) zmx = zmx + (2 * zstp - zmx % zstp) ct = np.array([ np.linspace(zmn, zmx, int(np.ceil(zmn / zstp))), Kos.comoving_distance(np.linspace(zmn, zmx, int(np.ceil(zmn / zstp)))).value ]).T r2z = interpolate.pchip(*ct[:, ::-1].T) z = r2z(r) return z, ra, dec
def Compute_Pec_Vel(self, hubble, vel): toret=np.zeros(vel.shape) for i in range(vel.shape[0]): flow=hubble+vel[i, :] comoving=flow/(self.cosmo.H(self.redshift)*self.cosmo.scale_factor(self.redshift)*u.Mpc*u.s/u.km) flow_redshift=np.zeros(np.size(comoving)) for j in range(np.size(comoving)): flow_redshift[j]=ac.z_at_value(self.cosmo.comoving_distance, comoving[j]*u.Mpc)-self.redshift[j] toret[i, :]=3*10**5*flow_redshift/self.redshift return toret
def toSky(cs, H0, Om_m, zstep): """Convert redshift, RA, and Dec to comoving coordinates. Parameters ---------- cs : ndarray Comoving xyz-coordinates table [x,y,z], assuming input cosmology. H0 : float Hubble's constant in km/s/Mpc. Om_m : float Value of matter density. zstep : float Redshift step size for converting distance to redshift. Returns ------- z : float Object redshift. ra : float Object right ascension, in decimal degrees. dec : float Object declination, in decimal degrees. """ Kos = FlatLambdaCDM(H0, Om_m) c1 = cs.T[0] c2 = cs.T[1] c3 = cs.T[2] r = np.sqrt(c1**2. + c2**2. + c3**2.) dec = np.arcsin(c3 / r) / D2R ra = (np.arccos(c1 / np.sqrt(c1**2. + c2**2.)) * np.sign(c2) / D2R) % 360 zmn = z_at_value(Kos.comoving_distance, np.amin(r) * u.Mpc) zmx = z_at_value(Kos.comoving_distance, np.amax(r) * u.Mpc) zmn = zmn - (zstep + zmn % zstep) zmx = zmx + (2 * zstep - zmx % zstep) ct = np.array([ np.linspace(zmn, zmx, int(np.ceil(zmn / zstep))), Kos.comoving_distance(np.linspace(zmn, zmx, int(np.ceil(zmn / zstep)))).value ]).T r2z = interpolate.pchip(*ct[:, ::-1].T) z = r2z(r) #z = H0*r/c return z, ra, dec
def get_sf_qt_mass_lookback_time_bins(self, tnodes, mnodes): self.id_lookt_mass = {} age_universe = cosmo.age(0).value # 13.797617455819209 Gyr znodes = np.array([z_at_value(cosmo.age,(age_universe - i) * u.Gyr) for i in tnodes]) for iz in range(len(znodes[:-1])): for jm in range(len(mnodes[:-1])): ind_mt_sf =( (self.table.sfg == 1) & (self.table[self.zkey] >= np.min(znodes[iz:iz+2])) & (self.table[self.zkey] < np.max(znodes[iz:iz+2])) & (10**self.table[self.mkey] >= 10**np.min(mnodes[jm:jm+2])) & (10**self.table[self.mkey] < 10**np.max(mnodes[jm:jm+2])) ) ind_mt_qt =( (self.table.sfg == 0) & (self.table[self.zkey] >= np.min(znodes[iz:iz+2])) & (self.table[self.zkey] < np.max(znodes[iz:iz+2])) & (10**self.table[self.mkey] >= 10**np.min(mnodes[jm:jm+2])) & (10**self.table[self.mkey] < 10**np.max(mnodes[jm:jm+2])) ) self.id_lookt_mass['lookt_'+clean_args(str('{:.2f}'.format(tnodes[iz])))+'_'+clean_args(str('{:.2f}'.format(tnodes[iz+1])))+'__m_'+clean_args(str('{:.2f}'.format(mnodes[jm])))+'_'+clean_args(str('{:.2f}'.format(mnodes[jm+1])))+'_sf'] = self.table.ID[ind_mt_sf].values self.id_lookt_mass['lookt_'+clean_args(str('{:.2f}'.format(tnodes[iz])))+'_'+clean_args(str('{:.2f}'.format(tnodes[iz+1])))+'__m_'+clean_args(str('{:.2f}'.format(mnodes[jm])))+'_'+clean_args(str('{:.2f}'.format(mnodes[jm+1])))+'_qt'] = self.table.ID[ind_mt_qt].values
def get_subpop_ids(self, znodes, mnodes, pop_dict, linear_mass=1, lookback_time = False): self.subpop_ids = {} if lookback_time == True: age_universe = cosmo.age(0).value # 13.797617455819209 Gyr znodes = np.array([z_at_value(cosmo.age,(age_universe - i) * u.Gyr) for i in znodes]) for iz in range(len(znodes[:-1])): for jm in range(len(mnodes[:-1])): for k in pop_dict: if linear_mass == 1: ind_mz =( (self.table.sfg.values == pop_dict[k][0]) & (self.table[self.zkey] >= np.min(znodes[iz:iz+2])) & (self.table[self.zkey] < np.max(znodes[iz:iz+2])) & (10**self.table[self.mkey] >= 10**np.min(mnodes[jm:jm+2])) & (10**self.table[self.mkey] < 10**np.max(mnodes[jm:jm+2])) ) else: ind_mz =( (self.table.sfg == pop_dict[k][0]) & (self.table[self.zkey] >= np.min(znodes[iz:iz+2])) & (self.table[self.zkey] < np.max(znodes[iz:iz+2])) & (self.table[self.mkey] >= np.min(mnodes[jm:jm+2])) & (self.table[self.mkey] < np.max(mnodes[jm:jm+2])) ) self.subpop_ids['z_'+clean_args(str('{:.2f}'.format(znodes[iz])))+'_'+clean_args(str('{:.2f}'.format(znodes[iz+1])))+'__m_'+clean_args(str('{:.2f}'.format(mnodes[jm])))+'_'+clean_args(str('{:.2f}'.format(mnodes[jm+1])))+'_'+k] = self.table.ID[ind_mz].values
features = ['bar', 'odd', 'spiral'] z_range = np.arange(0.01, 0.2, 0.01) nz = len(z_range) mag_range = np.arange(-18.89, -21.89, -0.5) nm = len(mag_range) root_range = ['whole', 'bar'] nr = len(root_range) gal['z'] = np.repeat(z_range, nm * nr) gal['Mr'] = np.tile(np.repeat(mag_range, nr), np.array(nz)) gal['root'] = np.tile(root_range, np.array(nz * nm)) # 计算 fraction calculate_fraction() # 先计算绝对星等对应的红移 cut, 然后画图 flatui = ["#9b59b6", "#3498db", "#95a5a6", "#e74c3c", "#34495e", "#2ecc71"] redshift_cut = [COS.z_at_value(LambdaCDM(H0=70, Om0=0.3, Ode0=0.7).distmod, (17 - mag) * unit.mag) for mag in mag_range] gal = pd.read_csv('gal.csv') g = sns.FacetGrid(gal, hue='root', col='Mr', col_wrap=3, col_order=mag_range, palette=flatui) g.map(plt.plot, 'z', 'fraction') g.add_legend() g.set(ylim=(0, .5)) i = 0 for ax in g.axes.ravel(): ax.plot([redshift_cut[i], redshift_cut[i]], [0, 1], 'k--') ax.text(redshift_cut[i] + 0.01, 0.45, 'z=%f' % redshift_cut[i], fontsize=10, bbox=dict(facecolor='#95a5a6', alpha=0.4)) i += 1 plt.show()
def do_cleanup(catalog): """Task to cleanup catalog before final write.""" task_str = catalog.get_current_task_str() # Set preferred names, calculate some columns based on imported data, # sanitize some fields keys = catalog.entries.copy().keys() cleanupcnt = 0 for oname in pbar(keys, task_str): name = catalog.add_entry(oname) # Set the preferred name, switching to that name if name changed. name = catalog.entries[name].set_preferred_name() aliases = catalog.entries[name].get_aliases() catalog.entries[name].set_first_max_light() if TIDALDISRUPTION.DISCOVER_DATE not in catalog.entries[name]: prefixes = ['MLS', 'SSS', 'CSS', 'GRB '] for alias in aliases: for prefix in prefixes: if (alias.startswith(prefix) and is_number(alias.replace(prefix, '')[:2])): discoverdate = ('/'.join([ '20' + alias.replace(prefix, '')[:2], alias.replace(prefix, '')[2:4], alias.replace(prefix, '')[4:6] ])) if catalog.args.verbose: tprint('Added discoverdate from name [' + alias + ']: ' + discoverdate) source = catalog.entries[name].add_self_source() catalog.entries[name].add_quantity( TIDALDISRUPTION.DISCOVER_DATE, discoverdate, source, derived=True) break if TIDALDISRUPTION.DISCOVER_DATE in catalog.entries[name]: break if TIDALDISRUPTION.DISCOVER_DATE not in catalog.entries[name]: prefixes = [ 'ASASSN-', 'PS1-', 'PS1', 'PS', 'iPTF', 'PTF', 'SCP-', 'SNLS-', 'SPIRITS', 'LSQ', 'DES', 'SNHiTS', 'Gaia', 'GND', 'GNW', 'GSD', 'GSW', 'EGS', 'COS', 'OGLE', 'HST' ] for alias in aliases: for prefix in prefixes: if (alias.startswith(prefix) and is_number(alias.replace(prefix, '')[:2]) and is_number(alias.replace(prefix, '')[:1])): discoverdate = '20' + alias.replace(prefix, '')[:2] if catalog.args.verbose: tprint('Added discoverdate from name [' + alias + ']: ' + discoverdate) source = catalog.entries[name].add_self_source() catalog.entries[name].add_quantity( TIDALDISRUPTION.DISCOVER_DATE, discoverdate, source, derived=True) break if TIDALDISRUPTION.DISCOVER_DATE in catalog.entries[name]: break if TIDALDISRUPTION.DISCOVER_DATE not in catalog.entries[name]: prefixes = ['SNF'] for alias in aliases: for prefix in prefixes: if (alias.startswith(prefix) and is_number(alias.replace(prefix, '')[:4])): discoverdate = ('/'.join([ alias.replace(prefix, '')[:4], alias.replace(prefix, '')[4:6], alias.replace(prefix, '')[6:8] ])) if catalog.args.verbose: tprint('Added discoverdate from name [' + alias + ']: ' + discoverdate) source = catalog.entries[name].add_self_source() catalog.entries[name].add_quantity( TIDALDISRUPTION.DISCOVER_DATE, discoverdate, source, derived=True) break if TIDALDISRUPTION.DISCOVER_DATE in catalog.entries[name]: break if TIDALDISRUPTION.DISCOVER_DATE not in catalog.entries[name]: prefixes = ['PTFS', 'SNSDF'] for alias in aliases: for prefix in prefixes: if (alias.startswith(prefix) and is_number(alias.replace(prefix, '')[:2])): discoverdate = ('/'.join([ '20' + alias.replace(prefix, '')[:2], alias.replace(prefix, '')[2:4] ])) if catalog.args.verbose: tprint('Added discoverdate from name [' + alias + ']: ' + discoverdate) source = catalog.entries[name].add_self_source() catalog.entries[name].add_quantity( TIDALDISRUPTION.DISCOVER_DATE, discoverdate, source, derived=True) break if TIDALDISRUPTION.DISCOVER_DATE in catalog.entries[name]: break if TIDALDISRUPTION.DISCOVER_DATE not in catalog.entries[name]: prefixes = ['AT', 'SN', 'OGLE-', 'SM ', 'KSN-'] for alias in aliases: for prefix in prefixes: if alias.startswith(prefix): year = re.findall(r'\d+', alias) if len(year) == 1: year = year[0] else: continue if alias.replace(prefix, '').index(year) != 0: continue if (year and is_number(year) and '.' not in year and len(year) <= 4): discoverdate = year if catalog.args.verbose: tprint('Added discoverdate from name [' + alias + ']: ' + discoverdate) source = catalog.entries[name].add_self_source() catalog.entries[name].add_quantity( TIDALDISRUPTION.DISCOVER_DATE, discoverdate, source, derived=True) break if TIDALDISRUPTION.DISCOVER_DATE in catalog.entries[name]: break if (TIDALDISRUPTION.RA not in catalog.entries[name] or TIDALDISRUPTION.DEC not in catalog.entries[name]): prefixes = [ 'PSN J', 'MASJ', 'CSS', 'SSS', 'MASTER OT J', 'HST J', 'TCP J', 'MACS J', '2MASS J', 'EQ J', 'CRTS J', 'SMT J' ] for alias in aliases: for prefix in prefixes: if (alias.startswith(prefix) and is_number(alias.replace(prefix, '')[:6])): noprefix = alias.split(':')[-1].replace( prefix, '').replace('.', '') decsign = '+' if '+' in noprefix else '-' noprefix = noprefix.replace('+', '|').replace('-', '|') nops = noprefix.split('|') if len(nops) < 2: continue rastr = nops[0] decstr = nops[1] ra = ':'.join([rastr[:2], rastr[2:4], rastr[4:6]]) + \ ('.' + rastr[6:] if len(rastr) > 6 else '') dec = (decsign + ':'.join( [decstr[:2], decstr[2:4], decstr[4:6]]) + ('.' + decstr[6:] if len(decstr) > 6 else '')) if catalog.args.verbose: tprint('Added ra/dec from name: ' + ra + ' ' + dec) source = catalog.entries[name].add_self_source() catalog.entries[name].add_quantity( TIDALDISRUPTION.RA, ra, source, derived=True) catalog.entries[name].add_quantity( TIDALDISRUPTION.DEC, dec, source, derived=True) break if TIDALDISRUPTION.RA in catalog.entries[name]: break no_host = (TIDALDISRUPTION.HOST not in catalog.entries[name] or not any([ x[QUANTITY.VALUE] == 'Milky Way' for x in catalog.entries[name][TIDALDISRUPTION.HOST] ])) if (TIDALDISRUPTION.RA in catalog.entries[name] and TIDALDISRUPTION.DEC in catalog.entries[name] and no_host): from astroquery.irsa_dust import IrsaDust if name not in catalog.extinctions_dict: try: ra_dec = (catalog.entries[name][TIDALDISRUPTION.RA][0][ QUANTITY.VALUE] + " " + catalog.entries[name][ TIDALDISRUPTION.DEC][0][QUANTITY.VALUE]) result = IrsaDust.get_query_table(ra_dec, section='ebv') except (KeyboardInterrupt, SystemExit): raise except Exception: warnings.warn("Coordinate lookup for " + name + " failed in IRSA.") else: ebv = result['ext SandF mean'][0] ebverr = result['ext SandF std'][0] catalog.extinctions_dict[name] = [ebv, ebverr] if name in catalog.extinctions_dict: sources = uniq_cdl([ catalog.entries[name].add_self_source(), catalog.entries[name] .add_source(bibcode='2011ApJ...737..103S') ]) (catalog.entries[name].add_quantity( TIDALDISRUPTION.EBV, str(catalog.extinctions_dict[name][0]), sources, e_value=str(catalog.extinctions_dict[name][1]), derived=True)) if ((TIDALDISRUPTION.HOST in catalog.entries[name] and (TIDALDISRUPTION.HOST_RA not in catalog.entries[name] or TIDALDISRUPTION.HOST_DEC not in catalog.entries[name]))): for host in catalog.entries[name][TIDALDISRUPTION.HOST]: alias = host[QUANTITY.VALUE] if ' J' in alias and is_number(alias.split(' J')[-1][:6]): noprefix = alias.split(' J')[-1].split(':')[-1].replace( '.', '') decsign = '+' if '+' in noprefix else '-' noprefix = noprefix.replace('+', '|').replace('-', '|') nops = noprefix.split('|') if len(nops) < 2: continue rastr = nops[0] decstr = nops[1] hostra = (':'.join([rastr[:2], rastr[2:4], rastr[4:6]]) + ('.' + rastr[6:] if len(rastr) > 6 else '')) hostdec = decsign + ':'.join([ decstr[:2], decstr[2:4], decstr[4:6] ]) + ('.' + decstr[6:] if len(decstr) > 6 else '') if catalog.args.verbose: tprint('Added hostra/hostdec from name: ' + hostra + ' ' + hostdec) source = catalog.entries[name].add_self_source() catalog.entries[name].add_quantity( TIDALDISRUPTION.HOST_RA, hostra, source, derived=True) catalog.entries[name].add_quantity( TIDALDISRUPTION.HOST_DEC, hostdec, source, derived=True) break if TIDALDISRUPTION.HOST_RA in catalog.entries[name]: break if (TIDALDISRUPTION.REDSHIFT not in catalog.entries[name] and TIDALDISRUPTION.VELOCITY in catalog.entries[name]): # Find the "best" velocity to use for this bestsig = 0 for hv in catalog.entries[name][TIDALDISRUPTION.VELOCITY]: sig = get_sig_digits(hv[QUANTITY.VALUE]) if sig > bestsig: besthv = hv[QUANTITY.VALUE] bestsrc = hv['source'] bestsig = sig if bestsig > 0 and is_number(besthv): voc = float(besthv) * 1.e5 / CLIGHT source = catalog.entries[name].add_self_source() sources = uniq_cdl([source] + bestsrc.split(',')) (catalog.entries[name].add_quantity( TIDALDISRUPTION.REDSHIFT, pretty_num( sqrt((1. + voc) / (1. - voc)) - 1., sig=bestsig), sources, kind='heliocentric', derived=True)) if (TIDALDISRUPTION.REDSHIFT not in catalog.entries[name] and len(catalog.nedd_dict) > 0 and TIDALDISRUPTION.HOST in catalog.entries[name]): reference = "NED-D" refurl = "http://ned.ipac.caltech.edu/Library/Distances/" for host in catalog.entries[name][TIDALDISRUPTION.HOST]: if host[QUANTITY.VALUE] in catalog.nedd_dict: source = catalog.entries[name].add_source( bibcode='2016A&A...594A..13P') secondarysource = catalog.entries[name].add_source( name=reference, url=refurl, secondary=True) meddist = statistics.median(catalog.nedd_dict[host[ QUANTITY.VALUE]]) redz = z_at_value(cosmo.comoving_distance, float(meddist) * un.Mpc) redshift = pretty_num( redz, sig=get_sig_digits(str(meddist))) catalog.entries[name].add_quantity( TIDALDISRUPTION.REDSHIFT, redshift, uniq_cdl([source, secondarysource]), kind='host', derived=True) if (TIDALDISRUPTION.MAX_ABS_MAG not in catalog.entries[name] and TIDALDISRUPTION.MAX_APP_MAG in catalog.entries[name] and TIDALDISRUPTION.LUM_DIST in catalog.entries[name]): # Find the "best" distance to use for this bestsig = 0 for ld in catalog.entries[name][TIDALDISRUPTION.LUM_DIST]: sig = get_sig_digits(ld[QUANTITY.VALUE]) if sig > bestsig: bestld = ld[QUANTITY.VALUE] bestsrc = ld['source'] bestsig = sig if bestsig > 0 and is_number(bestld) and float(bestld) > 0.: source = catalog.entries[name].add_self_source() sources = uniq_cdl([source] + bestsrc.split(',')) bestldz = z_at_value(cosmo.luminosity_distance, float(bestld) * un.Mpc) pnum = (float(catalog.entries[name][ TIDALDISRUPTION.MAX_APP_MAG][0][QUANTITY.VALUE]) - 5.0 * (log10(float(bestld) * 1.0e6) - 1.0 ) + 2.5 * log10(1.0 + bestldz)) pnum = pretty_num(pnum, sig=bestsig) catalog.entries[name].add_quantity( TIDALDISRUPTION.MAX_ABS_MAG, pnum, sources, derived=True) if TIDALDISRUPTION.REDSHIFT in catalog.entries[name]: # Find the "best" redshift to use for this bestz, bestkind, bestsig, bestsrc = catalog.entries[ name].get_best_redshift() if bestsig > 0: try: bestz = float(bestz) except Exception: print(catalog.entries[name]) raise if TIDALDISRUPTION.VELOCITY not in catalog.entries[name]: source = catalog.entries[name].add_self_source() # FIX: what's happening here?! pnum = CLIGHT / KM * \ ((bestz + 1.)**2. - 1.) / ((bestz + 1.)**2. + 1.) pnum = pretty_num(pnum, sig=bestsig) catalog.entries[name].add_quantity( TIDALDISRUPTION.VELOCITY, pnum, source, kind=PREF_KINDS[bestkind], derived=True) if bestz > 0.: from astropy.cosmology import Planck15 as cosmo if TIDALDISRUPTION.LUM_DIST not in catalog.entries[name]: dl = cosmo.luminosity_distance(bestz) sources = [ catalog.entries[name].add_self_source(), catalog.entries[name] .add_source(bibcode='2016A&A...594A..13P') ] sources = uniq_cdl(sources + bestsrc.split(',')) catalog.entries[name].add_quantity( TIDALDISRUPTION.LUM_DIST, pretty_num( dl.value, sig=bestsig), sources, kind=PREF_KINDS[bestkind], derived=True) if (TIDALDISRUPTION.MAX_ABS_MAG not in catalog.entries[name] and TIDALDISRUPTION.MAX_APP_MAG in catalog.entries[name]): source = catalog.entries[name].add_self_source() pnum = pretty_num( float(catalog.entries[name][ TIDALDISRUPTION.MAX_APP_MAG][0][ QUANTITY.VALUE]) - 5.0 * (log10(dl.to('pc').value) - 1.0 ) + 2.5 * log10(1.0 + bestz), sig=bestsig + 1) catalog.entries[name].add_quantity( TIDALDISRUPTION.MAX_ABS_MAG, pnum, sources, derived=True) if TIDALDISRUPTION.COMOVING_DIST not in catalog.entries[ name]: cd = cosmo.comoving_distance(bestz) sources = [ catalog.entries[name].add_self_source(), catalog.entries[name] .add_source(bibcode='2016A&A...594A..13P') ] sources = uniq_cdl(sources + bestsrc.split(',')) catalog.entries[name].add_quantity( TIDALDISRUPTION.COMOVING_DIST, pretty_num( cd.value, sig=bestsig), sources, derived=True) if all([ x in catalog.entries[name] for x in [ TIDALDISRUPTION.RA, TIDALDISRUPTION.DEC, TIDALDISRUPTION.HOST_RA, TIDALDISRUPTION.HOST_DEC ] ]): # For now just using first coordinates that appear in entry try: c1 = coord( ra=catalog.entries[name][TIDALDISRUPTION.RA][0][ QUANTITY.VALUE], dec=catalog.entries[name][TIDALDISRUPTION.DEC][0][ QUANTITY.VALUE], unit=(un.hourangle, un.deg)) c2 = coord( ra=catalog.entries[name][TIDALDISRUPTION.HOST_RA][0][ QUANTITY.VALUE], dec=catalog.entries[name][TIDALDISRUPTION.HOST_DEC][0][ QUANTITY.VALUE], unit=(un.hourangle, un.deg)) except (KeyboardInterrupt, SystemExit): raise except Exception: pass else: sources = uniq_cdl( [catalog.entries[name].add_self_source()] + catalog. entries[name][TIDALDISRUPTION.RA][0]['source'].split(',') + catalog.entries[name][TIDALDISRUPTION.DEC][0]['source']. split(',') + catalog.entries[name][TIDALDISRUPTION.HOST_RA] [0]['source'].split(',') + catalog.entries[name][ TIDALDISRUPTION.HOST_DEC][0]['source'].split(',')) if 'hostoffsetang' not in catalog.entries[name]: hosa = Decimal( hypot(c1.ra.degree - c2.ra.degree, c1.dec.degree - c2.dec.degree)) hosa = pretty_num(hosa * Decimal(3600.)) catalog.entries[name].add_quantity( TIDALDISRUPTION.HOST_OFFSET_ANG, hosa, sources, derived=True, u_value='arcseconds') if (TIDALDISRUPTION.COMOVING_DIST in catalog.entries[name] and TIDALDISRUPTION.REDSHIFT in catalog.entries[name] and TIDALDISRUPTION.HOST_OFFSET_DIST not in catalog.entries[name]): offsetsig = get_sig_digits(catalog.entries[name][ TIDALDISRUPTION.HOST_OFFSET_ANG][0][QUANTITY.VALUE]) sources = uniq_cdl( sources.split(',') + (catalog.entries[name][ TIDALDISRUPTION.COMOVING_DIST][0]['source']). split(',') + (catalog.entries[name][ TIDALDISRUPTION.REDSHIFT][0]['source']).split(',')) (catalog.entries[name].add_quantity( TIDALDISRUPTION.HOST_OFFSET_DIST, pretty_num( float(catalog.entries[name][ TIDALDISRUPTION.HOST_OFFSET_ANG][0][ QUANTITY.VALUE]) / 3600. * (pi / 180.) * float(catalog.entries[name][ TIDALDISRUPTION.COMOVING_DIST][0][ QUANTITY.VALUE]) * 1000. / (1.0 + float(catalog.entries[name][ TIDALDISRUPTION.REDSHIFT][0][QUANTITY.VALUE])), sig=offsetsig), sources)) catalog.entries[name].sanitize() catalog.journal_entries(bury=True, final=True, gz=True) cleanupcnt = cleanupcnt + 1 if catalog.args.travis and cleanupcnt % 1000 == 0: break catalog.save_caches() return
def do_nedd(catalog): task_str = catalog.get_current_task_str() nedd_path = os.path.join( catalog.get_current_task_repo(), 'NED26.05.1-D-12.1.0-20160501.csv') f = open(nedd_path, 'r') data = sorted(list(csv.reader(f, delimiter=',', quotechar='"'))[ 13:], key=lambda x: (x[9], x[3])) reference = "NED-D" refurl = "http://ned.ipac.caltech.edu/Library/Distances/" nedd_dict = OrderedDict() olddistname = '' for r, row in enumerate(pbar(data, task_str)): if r <= 12: continue distname = row[3] name = name_clean(distname) # distmod = row[4] # moderr = row[5] dist = row[6] bibcode = unescape(row[8]) snname = name_clean(row[9]) redshift = row[10] cleanhost = '' if name != snname and (name + ' HOST' != snname): cleanhost = host_clean(distname) if cleanhost.endswith(' HOST'): cleanhost = '' if not is_number(dist): print(dist) if dist: nedd_dict.setdefault(cleanhost, []).append(Decimal(dist)) if snname and 'HOST' not in snname: snname, secondarysource = catalog.new_entry( snname, srcname=reference, url=refurl, secondary=True) if bibcode: source = catalog.entries[snname].add_source(bibcode=bibcode) sources = uniq_cdl([source, secondarysource]) else: sources = secondarysource if name == snname: if redshift: catalog.entries[snname].add_quantity( 'redshift', redshift, sources) if dist: catalog.entries[snname].add_quantity( 'comovingdist', dist, sources) if not redshift: try: zatval = z_at_value(cosmo.comoving_distance, float(dist) * un.Mpc, zmax=5.0) sigd = get_sig_digits(str(dist)) redshift = pretty_num(zatval, sig=sigd) except (KeyboardInterrupt, SystemExit): raise except: pass else: cosmosource = catalog.entries[name].add_source( bibcode='2016A&A...594A..13P') combsources = uniq_cdl(sources.split(',') + [cosmosource]) catalog.entries[snname].add_quantity('redshift', redshift, combsources) if cleanhost: catalog.entries[snname].add_quantity( 'host', cleanhost, sources) if catalog.args.update and olddistname != distname: catalog.journal_entries() olddistname = distname catalog.journal_entries() f.close() return
d = list() for model in batch.available: d.append(model.cosmology.comoving_distance(zmax)) #Compute lens spacings d = np.array([dv.value for dv in d]) * d[0].unit #We want to make sure there are lenses up to the maximum of these distances lens_distances = np.arange(lens_thickness_Mpc,d.max().to(u.Mpc).value + lens_thickness_Mpc,lens_thickness_Mpc) * u.Mpc for model in batch.available: #Compute the redshifts of the Gadget snapshots z = np.zeros_like(lens_distances.value) for n,dlens in enumerate(lens_distances): z[n] = z_at_value(model.cosmology.comoving_distance,dlens) #Assgn values to gadget settings gadget2.OutputScaleFactor = np.sort(1/(1+z)) if "--pfiles" in sys.argv: collection = model.collections[0] #Convert camb power spectra into ngenic ones collection.camb2ngenic(z=0.0) r = collection.realizations[0] #ngenic parameter file r.writeNGenIC(ngenic)
def cutPlaneGaussianGrid(self,normal=2,thickness=0.5*Mpc,center=7.0*Mpc,plane_resolution=4096,left_corner=None,thickness_resolution=1,smooth=1,kind="density",**kwargs): """ Cuts a density (or lensing potential) plane out of the snapshot by computing the particle number density on a slab and performing Gaussian smoothing; the plane coordinates are cartesian comoving :param normal: direction of the normal to the plane (0 is x, 1 is y and 2 is z) :type normal: int. (0,1,2) :param thickness: thickness of the plane :type thickness: float. with units :param center: location of the plane along the normal direction :type center: float. with units :param plane_resolution: plane resolution (perpendicular to the normal) :type plane_resolution: float. with units (or int.) :param left_corner: specify the position of the lower left corner of the box; if None, the minimum of the (x,y,z) of the contained particles is assumed :type left_corner: tuple of quantities or None :param thickness_resolution: plane resolution (along the normal) :type thickness_resolution: float. with units (or int.) :param smooth: if not None, performs a smoothing of the density (or potential) with a gaussian kernel of scale "smooth x the pixel resolution" :type smooth: int. or None :param kind: decide if computing a density or gravitational potential plane (this is computed solving the poisson equation) :type kind: str. ("density" or "potential") :param kwargs: accepted keyword are: 'density_placeholder', a pre-allocated numpy array, with a RMA window opened on it; this facilitates the communication with different processors by using a single RMA window during the execution. 'l_squared' a pre-computed meshgrid of squared multipoles used for smoothing :type kwargs: dict. :returns: tuple(numpy 2D array with the density (or lensing potential),bin resolution along the axes, number of particles on the plane) """ #Sanity checks assert normal in range(3),"There are only 3 dimensions!" assert kind in ["density","potential"],"Specify density or potential plane!" assert type(thickness)==quantity.Quantity and thickness.unit.physical_type=="length" assert type(center)==quantity.Quantity and center.unit.physical_type=="length" #Redshift must be bigger than 0 or we cannot proceed if ("redshift" in self.header) and (self.header["redshift"]<=0.0): raise ValueError("The snapshot redshift must be >0 for the lensing density to be defined!") #Cosmological normalization factor cosmo_normalization = 1.5 * self.header["H0"]**2 * self.header["Om0"] / c**2 #Direction of the plane plane_directions = [ d for d in range(3) if d!=normal ] #Get the particle positions if not available get if hasattr(self,"positions"): positions = self.positions else: positions = self.getPositions(first=self._first,last=self._last,save=False) assert hasattr(self,"weights") assert hasattr(self,"virial_radius") assert hasattr(self,"concentration") #Lower left corner of the plane if left_corner is None: left_corner = positions.min(axis=0) #Create a list that holds the bins binning = [None,None,None] #Binning in the longitudinal direction assert type(plane_resolution) in [np.int,quantity.Quantity] if type(plane_resolution)==quantity.Quantity: assert plane_resolution.unit.physical_type=="length" plane_resolution = plane_resolution.to(positions.unit) binning[plane_directions[0]] = np.arange(left_corner[plane_directions[0]].to(positions.unit).value,(left_corner[plane_directions[0]] + self._header["box_size"]).to(positions.unit).value,plane_resolution.value) binning[plane_directions[1]] = np.arange(left_corner[plane_directions[1]].to(positions.unit).value,(left_corner[plane_directions[1]] + self._header["box_size"]).to(positions.unit).value,plane_resolution.value) else: binning[plane_directions[0]] = np.linspace(left_corner[plane_directions[0]].to(positions.unit).value,(left_corner[plane_directions[0]] + self._header["box_size"]).to(positions.unit).value,plane_resolution+1) binning[plane_directions[1]] = np.linspace(left_corner[plane_directions[1]].to(positions.unit).value,(left_corner[plane_directions[1]] + self._header["box_size"]).to(positions.unit).value,plane_resolution+1) #Binning in the normal direction assert type(thickness_resolution) in [np.int,quantity.Quantity] center = center.to(positions.unit) thickness = thickness.to(positions.unit) if type(thickness_resolution)==quantity.Quantity: assert thickness_resolution.unit.physical_type=="length" thickness_resolution = thickness_resolution.to(positions.unit) binning[normal] = np.arange((center - thickness/2).to(positions.unit).value,(center + thickness/2).to(positions.unit).value,thickness_resolution.value) else: binning[normal] = np.linspace((center - thickness/2).to(positions.unit).value,(center + thickness/2).to(positions.unit).value,thickness_resolution+1) #Weights if self.weights is not None: weights = self.weights.astype(np.float32) else: weights = None #Virial radius if self.virial_radius is not None: assert weights is not None,"Particles have virial radiuses, you should specify their weight!" weights = (weights * self._header["num_particles_total"] / ((len(binning[0]) - 1) * (len(binning[1]) - 1) * (len(binning[2]) - 1))).astype(np.float32) rv = self.virial_radius.to(positions.unit).value else: rv = None #Recompute resolution to make sure it represents the bin size correctly bin_resolution = [ (binning[n][1:]-binning[n][:-1]).mean() * positions.unit for n in (0,1,2) ] ############################################################################################################ #################################Longitudinal normalization factor########################################## #If the comoving distance is not provided in the header, the position along the normal direction is assumed# ############################################################################################################ if "comoving_distance" in self.header: #Constant time snapshots density_normalization = bin_resolution[normal] * self.header["comoving_distance"] / self.header["scale_factor"] else: #Light cone projection: use the lens center as the common comoving distance zlens = z_at_value(self.cosmology.comoving_distance,center) density_normalization = bin_resolution[normal] * center * (1.+zlens) #Now use gridding to compute the density along the slab assert positions.value.dtype==np.float32 #Log if self.pool is not None: logplanes.debug("Task {0} began gridding procedure".format(self.pool.rank)) else: logplanes.debug("Began gridding procedure") ########## #Gridding# ########## density = ext._nbody.grid3d_nfw(positions.value,tuple(binning),weights,rv,self.concentration) ################################################################################################################################### #Log if self.pool is not None: logplanes.debug("Task {0} done with gridding procedure".format(self.pool.rank)) else: logplanes.debug("Done with gridding procedure") if (self.pool is None) or (self.pool.is_master()): logstderr.debug("Done with gridding procedure: peak memory usage {0:.3f} (task)".format(peakMemory())) #Accumulate the density from the other processors if "density_placeholder" in kwargs.keys(): density_projected = kwargs["density_placeholder"] #Safety assert assert density_projected.shape==(density.shape[plane_directions[0]],density.shape[plane_directions[1]]) density_projected[:] = density.sum(normal) NumPartTask = density_projected.sum() if self.pool is not None: self.pool.comm.Barrier() #Log logplanes.debug("Task {0} collected {1:.3e} particles".format(self.pool.rank,NumPartTask)) #Compute how many particles in total shoud be collected (for checking) NumPartTotalExpected = np.zeros(1,dtype=np.float32) self.pool.comm.Reduce(np.array([NumPartTask]),NumPartTotalExpected) #Log if self.pool.is_master(): logplanes.debug("{0[0]:.3e} particles should be collected from tasks 0-{1}".format(NumPartTotalExpected,self.pool.size)) logplanes.debug("Communicating density between tasks...") self.pool.accumulate() else: #Project along the normal direction density_projected = density.sum(normal) NumPartTask = density_projected.sum() if self.pool is not None: #Log logplanes.debug("Task {0} collected {1:.3e} particles".format(self.pool.rank,NumPartTask)) self.pool.openWindow(density_projected) self.pool.accumulate() self.pool.closeWindow() #Safety barrier sync if self.pool is not None: self.pool.comm.Barrier() #Compute the number of particles on the plane NumPartTotal = density_projected.sum() #Log if (self.pool is not None) and self.pool.is_master(): logplanes.debug("Received particles from all tasks: collected {0:.3e} particles".format(NumPartTotal)) logstderr.debug("Received particles from all tasks: peak memory usage {0:.3f} (task)".format(peakMemory())) #If this task is not the master, we can return now if (self.pool is not None) and not(self.pool.is_master()): return (None,)*3 #Normalize the density to the density fluctuation density_projected /= self._header["num_particles_total"] density_projected *= (self._header["box_size"]**3 / (bin_resolution[0]*bin_resolution[1]*bin_resolution[2])).decompose().value ################################################################################################################################# ######################################Ready to solve poisson equation via FFTs################################################### ################################################################################################################################# bin_resolution.pop(normal) #If smoothing is enabled or potential calculations are needed, we need to FFT the density field if (smooth is not None) or kind=="potential": #Compute the multipoles if "l_squared" in kwargs.keys(): l_squared = kwargs["l_squared"] else: lx,ly = np.meshgrid(fftengine.fftfreq(density_projected.shape[0]),fftengine.rfftfreq(density_projected.shape[1]),indexing="ij") l_squared = lx**2 + ly**2 #Avoid dividing by 0 l_squared[0,0] = 1.0 #FFT the density field if (self.pool is None) or (self.pool.is_master()): logplanes.debug("Proceeding in density FFT operations...") density_ft = fftengine.rfftn(density_projected) #Zero out the zeroth frequency density_ft[0,0] = 0.0 if kind=="potential": #Find out the comoving distance if "comoving_distance" in self.header: chi = self.header["comoving_distance"] else: chi = center #Solve the poisson equation density_ft *= -2.0 * (bin_resolution[0] * bin_resolution[1] / chi**2).decompose().value / (l_squared * ((2.0*np.pi)**2)) if smooth is not None: #Perform the smoothing density_ft *= np.exp(-0.5*((2.0*np.pi*smooth)**2)*l_squared) #Revert the FFT lensing_potential = fftengine.irfftn(density_ft) if (self.pool is None) or (self.pool.is_master()): logplanes.debug("Done with density FFT operations...") logstderr.debug("Done with density FFT operations: peak memory usage {0:.3f} (task)".format(peakMemory())) else: lensing_potential = density_projected #Multiply by the normalization factors lensing_potential = lensing_potential * cosmo_normalization * density_normalization lensing_potential = lensing_potential.decompose() assert lensing_potential.unit.physical_type=="dimensionless" #Add units to lensing potential if kind=="potential": lensing_potential *= rad**2 else: lensing_potential = lensing_potential.value #Return return lensing_potential,bin_resolution,NumPartTotal
def masked_z_at_value(fn, val, *args, **kwargs): try: z = z_at_value(fn, val, *args, **kwargs) return z, False except: return 0., True
def do_nedd(catalog): task_str = catalog.get_current_task_str() nedd_path = os.path.join( catalog.get_current_task_repo(), 'NED26.10.1-D-13.1.0-20160930.csv') f = open(nedd_path, 'r') data = sorted(list(csv.reader(f, delimiter=',', quotechar='"'))[ 13:], key=lambda x: (x[9], x[3])) reference = "NED-D v" + nedd_path.split('-')[-2] refurl = "http://ned.ipac.caltech.edu/Library/Distances/" nedbib = "1991ASSL..171...89H" olddistname = '' loopcnt = 0 for r, row in enumerate(pbar(data, task_str)): if r <= 12: continue distname = row[3] name = name_clean(distname) # distmod = row[4] # moderr = row[5] dist = row[6] bibcode = unescape(row[8]) snname = name_clean(row[9]) redshift = row[10] cleanhost = '' if name != snname and (name + ' HOST' != snname): cleanhost = host_clean(distname) if cleanhost.endswith(' HOST') or cleanhost.startswith('SN'): cleanhost = '' if not is_number(dist): print(dist) if dist and cleanhost: catalog.nedd_dict.setdefault( cleanhost, []).append(Decimal(dist)) if snname and 'HOST' not in snname: snname, secondarysource = catalog.new_entry( snname, srcname=reference, bibcode=nedbib, url=refurl, secondary=True) if bibcode: source = catalog.entries[snname].add_source(bibcode=bibcode) sources = uniq_cdl([source, secondarysource]) else: sources = secondarysource if name == snname: if redshift: catalog.entries[snname].add_quantity( SUPERNOVA.REDSHIFT, redshift, sources) if dist: catalog.entries[snname].add_quantity( SUPERNOVA.COMOVING_DIST, dist, sources) if not redshift: try: zatval = z_at_value(cosmo.comoving_distance, float(dist) * un.Mpc, zmax=5.0) sigd = get_sig_digits(str(dist)) redshift = pretty_num(zatval, sig=sigd) except (KeyboardInterrupt, SystemExit): raise except Exception: pass else: cosmosource = catalog.entries[name].add_source( bibcode='2016A&A...594A..13P') combsources = uniq_cdl(sources.split(',') + [cosmosource]) catalog.entries[snname].add_quantity( SUPERNOVA.REDSHIFT, redshift, combsources, derived=True) if cleanhost: catalog.entries[snname].add_quantity( SUPERNOVA.HOST, cleanhost, sources) if catalog.args.update and olddistname != distname: catalog.journal_entries() olddistname = distname loopcnt = loopcnt + 1 if catalog.args.travis and loopcnt % catalog.TRAVIS_QUERY_LIMIT == 0: break catalog.journal_entries() f.close() return