def iterate_temp(gas, tol=1e-4, do_temp=True): """ Solve for the equilibrium temperature iteratively, given an initial pressure and the corresponding temperature assuming a mean molecular weight of unity. At each step the temperature is varied, the mean molecular mass recalculated according to the new temperature and the given pressure. The resulting temperatures are directly stored into the input snapshot. Parameters: ----------- gas : pynbody snapshot of gas particles, must have arrays 'temp' and 'pressure' Keyword argumens: ----------------- tol (1e-4) : relative tolerance level at which temperature is considered to be converged """ temp = gas['temp'].in_units('K').view(np.ndarray) pressure = gas['pressure'].in_units('g cm**-1 s**-2').view(np.ndarray) t_diff = np.ones(temp.shape) t_orig = temp t_old = temp mu = 1. if do_temp: mu = get_mu(mu * temp, pressure) else: mu = get_mu(temp, pressure / mu) mu_high = np.ones(mu.shape) mu_low = np.ones(mu.shape) high = np.where(mu > mu_high) low = np.where(mu < mu_low) mu_high[high] = mu[high] mu_low[low] = mu[low] mu_half = (mu_high + mu_low) / 2. while ((np.abs(mu_high - mu_low) / mu_low) > tol).any(): if do_temp: mu = get_mu(mu * temp, pressure) else: mu = get_mu(temp, pressure / mu) high = np.where(mu > mu_half) mu_low[high] = mu_half[high] low = np.where(mu <= mu_half) mu_high[low] = mu_half[low] mu_half = (mu_high + mu_low) / 2. gas['mu'] = mu_half if do_temp: gas['temp'] = array.SimArray(mu_half * temp, 'K') else: gas['pressure'] = array.SimArray(pressure / mu, 'g cm**-1 s**-2')
def __calc_enclosed_mass_of_R(self, R): """Calculate enclosed mass as function of polar distance""" z = np.append(0, np.logspace(-4, 0, 1000)) if not 0 in R: R = array.SimArray(np.append(0, R), R.units) Rs, Zs = np.meshgrid(R, z) Rs = array.SimArray(Rs, R.units) c = self.__gas_pars['c'] rs = self.__r_vir / c integrand = self.__gas_profile( np.sqrt(Rs * Rs + (c * c * rs * rs - Rs * Rs) * Zs * Zs).in_units( R.units), self.__gas_pars) * Rs integrand[np.where((Rs == 0) * (Zs == 0))] = 0. integrand = 0.5 * (integrand[1:, ] + integrand[:-1, ]) dz = z[1:] - z[:-1] rintegrand = (integrand.T * dz).T.sum(axis=0) zz = c * c * rs * rs - R * R zz[np.where(zz < 0)] *= 0 rintegrand *= np.sqrt(zz) rintegrand = 0.5 * (rintegrand[1:] + rintegrand[:-1]) dR = R[1:] - R[:-1] return 4. * np.pi * ((rintegrand * dR).cumsum()) * self.__f_bary
def __interpolate_jz_of_R(self): """Calculate angular momentum as a function of axisymmetric distance""" R = array.SimArray( np.logspace( np.log10(self._gas.sim['rxy'].min()), #np.log10(self._gas.sim['rxy'].max()), 1000), self.__r_s) np.log10(self._gas.sim['rxy'].max()), 1000), self._gas.sim['rxy'].units).in_units(self.__r_s) m_encl = self.__calc_enclosed_mass_of_R(R) m_encl /= m_encl.max() self.__invert_ang_mom_profile() jz = interp.splev(m_encl, self.__inverse_ang_mom_prof_tck) self.__jz_of_R_tck = interp.splrep(R.in_units('kpc'), jz, k=1)
def sample_equilibrium_halo(self): """This method actually creates the halo""" start = time.clock() print('SampleDarkHalo: setting positions ...'), sys.stdout.flush() self.__set_positions() pos_time = time.clock() print('done in {0:.2g} s'.format(pos_time - start)) if self.__do_velocities: print('SampleDarkHalo: calculating distribution function ...'), sys.stdout.flush() self.__calc_f() f_time = time.clock() print('done in {0:.2g} s'.format(f_time - pos_time)) print('SampleDarkHalo: setting velocities ...'), sys.stdout.flush() self.__set_velocities() v_time = time.clock() print(' done in {0:.2g} s'.format(v_time - f_time) + ' ' * 10) self.__set_softening() #self.__calc_r_vir() self.sim['mass'] = array.SimArray( np.ones(self.__n_particles) / self.__n_inside_r_vir, self.__m_vir) #self.sim['mass'].units = self.__m_vir self.sim['pos'] = array.SimArray(self.__pos, self.__r_s) #self.sim['pos'].units = self.__r_s self.sim['eps'] = array.SimArray( np.ones(self.__n_particles) * self.__eps, self.__r_s) #self.sim['eps'].units = self.__r_s if self.__do_velocities: self.__calc_vel_units() self.sim['vel'] = array.SimArray(self.__vel, self.__vel_fac) else: self.sim['vel'] = np.zeros(self.sim['vel'].shape) if self.__no_bulk_vel: self.sim['vel'] -= self.sim.mean_by_mass('vel') end = time.clock() print('SampleDarkHalo: halo created in {0:.2g} s'.format(end - start))
def __calc_temp(self): """Calculate the gas temperature based on its density and pressure""" # units rho_0 = 2. / 3. * self.__gas_pars[ 'c']**3 * self.__overden / self.__m_c_gas rho_0 *= tools.calc_rho_crit(self.__h) # density 1st guess dens = array.SimArray( np.interp(self._gas.sim['r'].in_units(self.__r_s_gas), self.__x_rho, self.__gas_profile(self.__x_rho, self.__gas_pars)), rho_0 / 2.) temp = (self.sim.g['pressure'] / dens / units.k * units.m_p).in_units('K') self.sim.g['temp'] = temp tools.iterate_temp(self._gas.sim)
def __calc_gravity_pressure(self): """ Solve the equation of hydrostatic equilibrium neglecting centrifugal effects of rotation """ integrand = lambda x: self.__gravity(x) * self.__gas_profile( x * self.__gas_pars['c'] / self.__pars['c'], self.__gas_pars) self.__p = array.SimArray( tools.simpsons_integral(self.__x_rho, integrand, norm_ind=-1)) self.__calc_m_c() unit = 4. * np.pi * self.__pars['c'] * self.__gas_pars[ 'c']**3 * self.__overden**2 unit /= 9. * self.__m_c * self.__m_c_gas unit *= units.G * self.__r_vir**2 * tools.calc_rho_crit(self.__h)**2 self.__p.units = tools.sim_array_to_unit(unit) self.sim.g['pressure'] += np.interp( self.sim.g['r'].in_units(self.__r_s), self.__x_rho, self.__p.in_units(self.sim.g['pressure'].units))
def __set_gas_velocities(self): """Set the gas velocities according to the specified angular momentum profile""" self.__interpolate_jz_of_R() vc = array.SimArray( interp.splev(self._gas.sim['rxy'].in_units('kpc'), self.__jz_of_R_tck), self.__j_max) vc /= self._gas.sim['rxy'] # Truncate velocity profile smoothly outside R_vir r_v = self.__r_vir vc *= tools.outer_smooth_cutoff( self._gas.sim['r'].in_units(r_v).view(np.ndarray), self.__vel_pars['factor']) # Quick and dirty hack due to some weird behaviour of the 'az' derived array in pynbody az = np.arctan2(self._gas.sim['y'], self._gas.sim['x']) #self._gas.sim['vel'].units = units.Unit('km s**-1') self._gas.sim['vel'][:, :-1] = ( np.array([-np.sin(az), np.cos(az)]) * vc.in_units(self.sim['vel'].units)).transpose() self._gas.sim['vel'][:, -1] = np.zeros(self.__n_gas_particles)
def __make_gas_sphere(self): """Sample the gas component of the halo but set velocities to 0""" prng = np.random.RandomState(self.__random_seed + 1) self._gas = SampleDarkHalo(profile=self.__gas_profile, pars=self.__gas_pars, m_vir=self.__m_vir, h=self.__h, overden=self.__overden, logxmin_rho=self.__logxmin_rho, logxmax_rho=self.__logxmax_rho, n_samlple_rho=self.__n_sample_rho, n_particles=self.__n_gas_particles, prng=prng, do_velocities=False, snap=self.sim.g) self._gas.sample_equilibrium_halo() #self._gas.finalize() self.sim.g['mass'] *= self.__f_bary self.sim.g['pressure'] = array.SimArray( np.zeros(self.__n_gas_particles), 'g cm**-1 s**-2')
def calculate(self, halo, exist): loaded_data_min_dm_mass = halo.dm['mass'].min() # If mass resolution is not present as a simulation property, # ensure backward compatibility by setting the min mass to infinity import numpy as np import pynbody.array as array simulation_min_dm_mass = array.SimArray(self.get_simulation_property("approx_resolution_Msol", default=np.inf), units="Msol") if np.isclose(loaded_data_min_dm_mass, simulation_min_dm_mass, rtol=1e-1, atol=1): # Loaded data contains some light particles. Tolerance of this test (agreement to 10% or to 1 Msol) # is sufficiently tight to separate heavy and light resolution, # while being broad enough to capture numerical inaccuracies coming # from the simulation mass resolution. n_heavy = (halo.dm['mass'] > loaded_data_min_dm_mass).sum() return float(n_heavy) / len(halo.dm) else: # Loaded data contains only "heavy" particles, e.g. an unzoomed halo in server mode return 1.0
def __init__(self, **kwargs): self.__kwargs = kwargs self.__profile = kwargs.get('profile', density_profiles.alphabetagamma) self.__drhodr = kwargs.get('drhodr', density_profiles.dalphabetagammadr) self.__d2rhodr2 = kwargs.get('d2rhodr2', density_profiles.d2alphabetagammadr2) self.__pars = kwargs.get('pars', { 'alpha': 1., 'beta': 3., 'gamma': 1., 'c': 10., 'factor': 0.1 }) if self.__profile == density_profiles.alphabetagamma and self.__pars[ 'beta'] <= 3.: if 'factor' not in self.__pars.keys(): self.__pars['factor'] = 0.1 self.__m_vir = kwargs.get('m_vir', '1e12 Msol') self.__m_vir = units.Unit(self.__m_vir) self.__h = kwargs.get('h', 0.7) self.__overden = kwargs.get('overden', 200.) self.__r_vir = tools.calc_r_vir(self.__m_vir, self.__h, self.__overden) self.__r_s = self.__r_vir / self.__pars['c'] self.__n_particles = int(kwargs.get('n_particles', 1e5)) self.__logxmax_rho = np.log10(self.__pars['c']) + 2. # Make sure to sample well inside the gravitational softening self.__logxmin_rho = self.__logxmax_rho - .5 * np.log10( self.__n_particles) - 3. self.__logxmin_dist_func = kwargs.get('logxmin_dist_func', -3.) self.__logxmax_dist_func = kwargs.get('logxmax_dist_func', 14.) self.__n_sample_rho = int(kwargs.get('n_sample_rho', 1e4)) self.__n_sample_dist_func = int(kwargs.get('n_sample_dist_func', 1e2)) self.__n_sample_dist_func_rho = int( kwargs.get('n_sample_dist_func_rho', 1e4)) self.__random_seed = kwargs.get('random_seed', 4) if 'prng' in kwargs.keys(): self.__prng = kwargs['prng'] else: self.__prng = np.random.RandomState(self.__random_seed) self.__spline_order = kwargs.get('spline_order', 3) self.__progress_bar = kwargs.get('progress_bar', False) self.__no_bulk_vel = kwargs.get('no_bulk_vel', True) self.__x_rho = np.logspace(self.__logxmin_rho, self.__logxmax_rho, self.__n_sample_rho) self.__f_bary = kwargs.get('f_bary', 0.1) self.__mu = kwargs.get('mu', 1.3) self.__spin_parameter = kwargs.get('spin_parameter', 0.04) self.__rot_balanced = kwargs.get('rot_balanced', False) # Different gas profiles are not yet implemented or successfully tested self.__gas_profile = self.__profile self.__gas_pars = self.__pars #self.__gas_profile = kwargs.get('gas_profile', density_profiles.alphabetagamma) #self.__gas_pars = kwargs.get('gas_pars', {'alpha': 1., 'beta': 3., 'gamma': 1., # 'c': 10., 'factor': 0.1}) self.__r_s_gas = self.__r_vir / self.__gas_pars['c'] #self.__vel_prof = kwargs.get('vel_prof', None) self.__vel_pars = kwargs.get( 'vel_pars', { 'rs_v': array.SimArray(1., 'kpc'), 'c': self.__pars['c'], 'prefac': 1., 'factor': 1. }) self.__n_gas_particles = int( kwargs.get('n_gas_particles', self.__n_particles)) self.__ang_mom_prof = kwargs.get('ang_mom_prof', am_profiles.bullock_prof) self.__ang_mom_pars = kwargs.get('ang_mom_pars', {'mu': self.__mu}) self.__fname = kwargs.get('fname', 'halo.out') # Careful here: as of now, only the output as tipsy files has been successfully tested self.__type = { 'gadget': gadget.GadgetSnap, 'grafic': grafic.GrafICSnap, 'nchilada': nchilada.NchiladaSnap, 'ramses': ramses.RamsesSnap, 'tipsy': tipsy.TipsySnap }[kwargs.get('type', 'tipsy')] self.sim = new(dm=self.__n_particles, gas=self.__n_gas_particles) self.sim.physical_units()
def trackIsoBH(simname, SF=False, filename=False, BeLazy=False): if not os.path.exists('files.list'): getFileLists(simname) f = open('files.list') files = f.readlines() distp = array.SimArray(np.zeros(len(files)), 'pc') xp = array.SimArray(np.zeros(len(files)), 'pc') yp = array.SimArray(np.zeros(len(files)), 'pc') zp = array.SimArray(np.zeros(len(files)), 'pc') vx = array.SimArray(np.zeros(len(files)), 'km s**-1') vy = array.SimArray(np.zeros(len(files)), 'km s**-1') vz = array.SimArray(np.zeros(len(files)), 'km s**-1') vcx = array.SimArray(np.zeros(len(files)), 'km s**-1') vcy = array.SimArray(np.zeros(len(files)), 'km s**-1') vcz = array.SimArray(np.zeros(len(files)), 'km s**-1') vrp = array.SimArray(np.zeros(len(files)), 'km s**-1') distc = array.SimArray(np.zeros(len(files)), 'pc') xc = array.SimArray(np.zeros(len(files)), 'pc') yc = array.SimArray(np.zeros(len(files)), 'pc') zc = array.SimArray(np.zeros(len(files)), 'pc') vrc = array.SimArray(np.zeros(len(files)), 'km s**-1') cnt = 0 time = array.SimArray(np.zeros(len(files)), 'Gyr') # time = (np.arange(len(files))+1)*outInterval*dt for sim in files: print "getting data from ", sim.strip('\n') s = pynbody.load(sim.strip('\n')) if BeLazy == False: cen = pynbody.analysis.halo.shrink_sphere_center(s) vcen = pynbody.analysis.halo.center_of_mass_velocity(s) cenpot = s['pos'][(s['phi'] == float(s['phi'].min()))] cenpot = cenpot[0] time[cnt] = s.properties['time'].in_units('Gyr') if SF == False: if BeLazy == False: vx[cnt] = s.stars['vx'].in_units('km s**-1')[0] vy[cnt] = s.stars['vx'].in_units('km s**-1')[0] vz[cnt] = s.stars['vx'].in_units('km s**-1')[0] s.stars['vel'] -= vcen vcx[cnt] = s.stars['vx'].in_units('km s**-1')[0] vcy[cnt] = s.stars['vy'].in_units('km s**-1')[0] vcz[cnt] = s.stars['vz'].in_units('km s**-1')[0] s.stars['pos'] -= cenpot xp[cnt] = s.stars['x'].in_units('pc')[0] yp[cnt] = s.stars['y'].in_units('pc')[0] zp[cnt] = s.stars['z'].in_units('pc')[0] if BeLazy == False: vrp[cnt] = s.stars['vr'].in_units('km s**-1')[0] distp[cnt] = s.stars['r'].in_units('pc')[0] s.stars['pos'] += cenpot if BeLazy == False: s.stars['pos'] -= cen xc[cnt] = s.stars['x'].in_units('pc')[0] yc[cnt] = s.stars['y'].in_units('pc')[0] zc[cnt] = s.stars['z'].in_units('pc')[0] if BeLazy == False: vrc[cnt] = s.stars['vr'].in_units('km s**-1')[0] distc[cnt] = s.stars['r'].in_units('pc')[0] cnt += 1 del (s) gc.collect() BHorbitInfo = { 'xp': xp, 'yp': yp, 'zp': zp, 'xc': xc, 'yc': yc, 'zc': zc, 'vrp': vrp, 'vrc': vrc, 'vx': vx, 'vy': vy, 'vz': vz, 'vcx': vcx, 'vcy': vcy, 'vcz': vcz, 'distp': distp, 'distc': distc, 'time': time } if filename: f = open(str(filename), 'wb') pickle.dump(BHorbitInfo, f) f.close() return BHorbitInfo
def getBHhalo(simname, findcenter='hyb', minHM=1e10, minNum=30, filename=None, initFile=None): if not os.path.exists("grpfiles.list"): simname_split = simname.split('.') num = len(simname_split) os.system('ls ' + simname + '.00*.grp | cut -d "." -f1-' + str(num + 1) + '> grpfiles.list') if filename: if os.path.exists(filename): print "file", filename, "already exists! reading it in and appending it with new data" f = open(filename, 'rb') BHhaloOLD = pickle.load(f) f.close() startStep = len(BHhaloOLD['haloID'][0]) os.system('rm ' + filename) print "old file has", startStep, "halos already completed" else: startStep = 0 if initFile: if os.path.exists(initFile): print "found file ", initFile, "reading it in now" f = open(initFile, 'rb') BHhaloOLD = pickle.load(f) f.close() startStep = len(BHhaloOLD['haloID'][0]) print "given file has", startStep, "halos already completed" if initFile == filename: print "given file has same name as target file... deleting old file to replace with new file" os.system('rm ' + filename) if initFile == None: startStep = 0 f = open("grpfiles.list") munits = 'Msol' vunits = 'km s**-1' posunits = 'kpc' cposunits = 'a kpc' print "finding BH iords..." bhiords = getBHiords(simname) files = f.readlines() f.close() nsteps = len(files) - startStep nbh = len(bhiords) bhmass = array.SimArray(np.zeros((nbh, nsteps)), munits) haloid = np.zeros((nbh, nsteps)) mhalo = array.SimArray(np.zeros((nbh, nsteps)), munits) mdark = array.SimArray(np.zeros((nbh, nsteps)), munits) mstar = array.SimArray(np.zeros((nbh, nsteps)), munits) mgas = array.SimArray(np.zeros((nbh, nsteps)), munits) #vhalo = array.SimArray(np.zeros((nbh,nsteps,3)),vunits) dist = array.SimArray(np.zeros((nbh, nsteps)), posunits) distcen = array.SimArray(np.zeros((nbh, nsteps)), posunits) bhpos = array.SimArray(np.zeros((nbh, nsteps, 3)), posunits) bhposcen = array.SimArray(np.zeros((nbh, nsteps, 3)), posunits) bhvel = array.SimArray(np.zeros((nbh, nsteps, 3)), vunits) bhvelcen = array.SimArray(np.zeros((nbh, nsteps, 3)), vunits) halorad = array.SimArray(np.zeros((nbh, nsteps)), posunits) scaleFac = np.zeros((nbh, nsteps)) interact = np.zeros((nbh, nsteps)) intpos = array.SimArray(np.zeros((nbh, nsteps, 3)), posunits) intvel = array.SimArray(np.zeros((nbh, nsteps, 3)), vunits) intdist = array.SimArray(np.zeros((nbh, nsteps)), posunits) #rho = array.SimArray(np.zeros((nbh,nsteps)),'g cm**-3') #cs = array.SimArray(np.zeros((nbh,nsteps)),'cm s**-1') for stepcnt in range(nsteps): line = files[stepcnt + startStep].strip() print "getting halo information for ", line s = pynbody.load(line) s.physical_units() cboxsize = 2 * s['x'].in_units('a kpc').max() simBH, = np.where(np.in1d(s.star['iord'], bhiords)) if not len(simBH): print "no BHs in this step! moving on..." continue boxsize = cboxsize.in_units('kpc') amigastat = readcol.readcol(line + '.amiga.stat', asdict=True) amigastat['cen'] = pynbody.array.SimArray( (np.array([amigastat['Xc'], amigastat['Yc'], amigastat['Zc']]).T * 1e3 - cboxsize / 2.) * s.properties['a'], posunits) h = s.halos() #simBH, = np.where(np.in1d(s.star['iord'],bhiords)) okgrp, = np.where(np.in1d(s.star['amiga.grp'][simBH], amigastat['Grp'])) simBH = simBH[okgrp] asort = np.argsort(s.star['iord'][simBH]) simBH = simBH[asort] simoutBH, = np.where(np.in1d(bhiords, s.star['iord'][simBH])) #outBH = np.where(np.in1d(bhiords,s.star['iord'][simBH])) print "there are ", len(simBH), "BHs in the step" allHaloID, invInd = np.unique(s.star['amiga.grp'][simBH], return_inverse=True) statind, = np.where(np.in1d(amigastat['Grp'], allHaloID)) #bad, = np.where(np.in1d(allHaloID,amigastat['Grp'])==False) #np.delete(allHaloID,bad) #badind, = np.where(np.in1d(invInd,bad)) #np.delete(invInd,badind) if not np.array_equal(allHaloID[invInd], amigastat['Grp'][statind[invInd]]): print "f**k!" return haloid[simoutBH, stepcnt] = allHaloID[invInd] mhalo[simoutBH, stepcnt] = pynbody.array.SimArray( amigastat['Mvir(M_sol)'][statind[invInd]], munits) mstar[simoutBH, stepcnt] = pynbody.array.SimArray( amigastat['StarMass(M_sol)'][statind[invInd]], munits) mgas[simoutBH, stepcnt] = pynbody.array.SimArray( amigastat['GasMass(M_sol)'][statind[invInd]], munits) mgas[simoutBH, stepcnt] = pynbody.array.SimArray( amigastat['GasMass(M_sol)'][statind[invInd]], munits) halorad[simoutBH, stepcnt] = pynbody.array.SimArray( amigastat['Rvir(kpc)'][statind[invInd]] * s.properties['a'], posunits) scaleFac[simoutBH, stepcnt] = s.properties['a'] vel = np.array([ amigastat['VXc'][statind[invInd]], amigastat['VYc'][statind[invInd]], amigastat['VZc'][statind[invInd]] ]).T bhvel[simoutBH, stepcnt, :] = s.stars['vel'][simBH].in_units(vunits) - vel postemp = s.stars['pos'][simBH].in_units(posunits) - amigastat['cen'][ statind[invInd]] postemp[(np.abs(postemp) > boxsize / 2.)] = -1.0 * ( postemp[(np.abs(postemp) > boxsize / 2.)] / np.abs(postemp[(np.abs(postemp) > boxsize / 2.)])) * ( boxsize - np.abs(postemp[(np.abs(postemp) > boxsize / 2.)])) bhpos[simoutBH, stepcnt, :] = postemp bhmass[simoutBH, stepcnt] = s.stars['mass'][simBH].in_units(munits) dist[simoutBH, stepcnt] = np.sqrt((bhpos[simoutBH, stepcnt, :]**2).sum(axis=1)) for cnt in range(len(allHaloID)): if allHaloID[cnt] == 0: continue print allHaloID[cnt] oo, = np.where(amigastat['Grp'] == allHaloID[cnt]) #cen = pynbody.array.SimArray([amigastat['Xc'][oo[0]],amigastat['Yc'][oo[0]],amigastat['Zc'][oo[0]]],posunits) if amigastat['Mvir(M_sol)'][ (amigastat['Grp'] == allHaloID[cnt])] < minHM and allHaloID[cnt] > minNum: continue okcenter = 1 try: pynbody.analysis.halo.center(h[allHaloID[cnt]], mode=findcenter, wrap=True, cen_size='2 kpc') except ValueError: okcenter = 0 pynbody.analysis.halo.center(h[allHaloID[cnt]], mode=findcenter, Wrap=True, cen_size='2 kpc', vel=False) haloBHs, = np.where( np.in1d(h[allHaloID[cnt]].star['iord'], bhiords)) outBH, = np.where( np.in1d(bhiords, h[allHaloID[cnt]].star['iord'][haloBHs])) #pynbody.transformation.inverse_translate(s,cen) closeBHs, = np.where((s.star['r'][simBH].in_units( 'kpc') < amigastat['Rvir(kpc)'][oo] * s.properties['a']) & (s.star['amiga.grp'][simBH] > allHaloID[cnt])) closeBHs = simBH[closeBHs] otheroutBHs, = np.where(np.in1d(bhiords, s.star['iord'][closeBHs])) bhposcen[outBH, stepcnt, :] = h[ allHaloID[cnt]].stars['pos'][haloBHs].in_units(posunits) distcen[outBH, stepcnt] = h[ allHaloID[cnt]].stars['r'][haloBHs].in_units(posunits) interact[otheroutBHs, stepcnt] = allHaloID[cnt] intpos[otheroutBHs, stepcnt, :] = s.stars['pos'][closeBHs].in_units(posunits) #intvel[otheroutBHs,stepcnt,:] = s.stars['vel'][closeBHs].in_units(vunits) intdist[otheroutBHs, stepcnt] = s.stars['r'][closeBHs].in_units(posunits) if okcenter == 1: intvel[otheroutBHs, stepcnt, :] = s.stars['vel'][closeBHs].in_units(vunits) bhvelcen[outBH, stepcnt, :] = h[ allHaloID[cnt]].stars['vel'][haloBHs].in_units(vunits) print "deleting stuff" del (s) del (h) gc.collect() bhhalo = { 'iord': bhiords, 'mass': bhmass, 'pos': bhpos, 'poscen': bhposcen, 'vel': bhvel, 'velcen': bhvelcen, 'haloID': haloid, 'halomass': mhalo, 'halostarmass': mstar, 'halodarkmass': mdark, 'halogasmass': mgas, 'rhalo': halorad, 'dist': dist, 'distcen': distcen, 'interact': interact, 'intdist': intdist, 'intvel': intvel, 'intpos': intpos, 'scaleFac': scaleFac } if startStep != 0: bhhalo['mass'] = np.append(BHhaloOLD['mass'], bhhalo['mass'], axis=1) bhhalo['pos'] = np.append(BHhaloOLD['pos'], bhhalo['pos'], axis=1) bhhalo['poscen'] = np.append(BHhaloOLD['poscen'], bhhalo['poscen'], axis=1) bhhalo['vel'] = np.append(BHhaloOLD['vel'], bhhalo['vel'], axis=1) bhhalo['velcen'] = np.append(BHhaloOLD['velcen'], bhhalo['velcen'], axis=1) bhhalo['haloID'] = np.append(BHhaloOLD['haloID'], bhhalo['haloID'], axis=1) bhhalo['halomass'] = np.append(BHhaloOLD['halomass'], bhhalo['halomass'], axis=1) bhhalo['halostarmass'] = np.append(BHhaloOLD['halostarmass'], bhhalo['halostarmass'], axis=1) bhhalo['halodarkmass'] = np.append(BHhaloOLD['halodarkmass'], bhhalo['halodarkmass'], axis=1) bhhalo['halogasmass'] = np.append(BHhaloOLD['halogasmass'], bhhalo['halogasmass'], axis=1) bhhalo['rhalo'] = np.append(BHhaloOLD['rhalo'], bhhalo['rhalo'], axis=1) bhhalo['dist'] = np.append(BHhaloOLD['dist'], bhhalo['dist'], axis=1) bhhalo['distcen'] = np.append(BHhaloOLD['distcen'], bhhalo['distcen'], axis=1) bhhalo['interact'] = np.append(BHhaloOLD['interact'], bhhalo['interact'], axis=1) bhhalo['intdist'] = np.append(BHhaloOLD['intdist'], bhhalo['intdist'], axis=1) bhhalo['intpos'] = np.append(BHhaloOLD['intpos'], bhhalo['intpos'], axis=1) bhhalo['intvel'] = np.append(BHhaloOLD['intvel'], bhhalo['intvel'], axis=1) bhhalo['scaleFac'] = np.append(BHhaloOLD['scaleFac'], bhhalo['scaleFac'], axis=1) if filename: f = open(str(filename), 'wb') pickle.dump(bhhalo, f) f.close() return bhhalo
def getBHorbit(simname, BHlist=[], filename=None): if not os.path.exists('files.list'): print "files.list not found. generating list of output files..." getFileLists(simname) print "getting all BH id numbers..." bhids = getBHiords(simname) files = open("files.list", 'r') f1 = files.readlines() s = pynbody.load(f1[0].strip('\n')) munits = s['mass'].units posunits = s['x'].units velunits = s['vx'].units potunits = s['phi'].units tunits = posunits / velunits Eunits = munits * potunits scaleUnit = pynbody.units.Unit('a') files.close() print posunits / scaleUnit print velunits / scaleUnit orbitfile = simname + ".orbit" #print "reading "+orbitfile+"...." #bhorbitData = readcol.readcol(orbitfile) #bhids = np.unique(bhorbitData[:,0]) if len(BHlist) > 0: matches = np.in1d(bhids, BHlist) bhorbit = {'iord': bhids[matches], 'data': np.array([])} else: bhorbit = {'iord': bhids, 'data': np.array([])} print "there are ", len(bhids), " BHs that have existed in this simulation" if len(BHlist) > 0: nBHs = len(BHlist) else: nBHs = len(bhids) print "getting data...." cnt = 0 os.system("awk -F ' ' '{print >$1}' " + orbitfile) print bhorbit['iord'] for id in bhids: print "getting data for BH ", id if len(BHlist) > 0: match, = np.where(BHlist == id) if len(match) == 0: os.system("rm " + str(np.int(id))) continue bhorbitData = readcol.readcol(str(np.int(id))) os.system("rm " + str(np.int(id))) bad, = np.where(bhorbitData[:, 0] != id) if len(bad) > 0: print "WARNING: bad ID found in miniorbit.txt file after awk... deleting" bhorbitData = np.delete(bhorbitData, bad, axis=0) cnt += 1 GoodScale = True print "BH #" + str(cnt) + "/" + str(len(bhids)) # curbh, = np.where(bhorbitData[:,0]==id) time = array.SimArray(bhorbitData[:, 1], tunits) step = bhorbitData[:, 2] mass = bhorbitData[:, 3] x = bhorbitData[:, 4] y = bhorbitData[:, 5] z = bhorbitData[:, 6] vx = bhorbitData[:, 7] vy = bhorbitData[:, 8] vz = bhorbitData[:, 9] pot = bhorbitData[:, 10] mdot = bhorbitData[:, 11] deltaM = bhorbitData[:, 12] E = bhorbitData[:, 13] dtEff = bhorbitData[:, 14] if len(bhorbitData[0, :]) < 16: print "uh oh, trying to find scale factor data, but cannot!" scaleFac = np.ones(len(bhorbitData[:, 1])) redshift = np.ones(len(bhorbitData[:, 1])) GoodScale = False else: scaleFac = bhorbitData[:, 15] redshift = 1 / scaleFac - 1 o = np.argsort(time) timeOrd = time[o] t1 = timeOrd[0:len(timeOrd) - 1] t2 = timeOrd[1:len(timeOrd)] bad = np.where(np.equal(t1, t2)) np.delete(o, bad) time = array.SimArray(time[o], tunits) step = step[o] mass = array.SimArray(mass[o], munits) x = array.SimArray(x[o] * scaleFac[o], posunits / scaleUnit) y = array.SimArray(y[o] * scaleFac[o], posunits / scaleUnit) z = array.SimArray(z[o] * scaleFac[o], posunits / scaleUnit) vx = array.SimArray(vx[o] * scaleFac[o], velunits / scaleUnit) vy = array.SimArray(vy[o] * scaleFac[o], velunits / scaleUnit) vz = array.SimArray(vz[o] * scaleFac[o], velunits / scaleUnit) pot = array.SimArray(pot[o], potunits) mdot = array.SimArray(mdot[o], munits / tunits) deltaM = array.SimArray(deltaM[o], munits) E = array.SimArray(E[o], Eunits) dtEff = array.SimArray(dtEff[o], tunits) scaleFac = scaleFac[o] redshift = redshift[o] if GoodScale: data = { 'Time': time, 'step': step, 'mass': mass.in_units('Msol'), 'x': x.in_units('kpc'), 'y': y.in_units('kpc'), 'z': z.in_units('kpc'), 'vx': vx.in_units('km s**-1'), 'vy': vy.in_units('km s**-1'), 'vz': vz.in_units('km s**-1'), 'pot': pot, 'mdot': mdot.in_units('Msol yr**-1'), 'dM': deltaM.in_units('Msol'), 'E': E, 'dt': dtEff, 'redshift': redshift, 'scaleFac': scaleFac } else: data = { 'Time': time, 'step': step, 'mass': mass.in_units('Msol'), 'x': x, 'y': y, 'z': z, 'vx': vx, 'vy': vy, 'vz': vz, 'pot': pot, 'mdot': mdot.in_units('Msol yr**-1'), 'dM': deltaM.in_units('Msol'), 'E': E, 'dt': dtEff, 'redshift': redshift, 'scaleFac': scaleFac } bhorbit['data'] = np.append(bhorbit['data'], data) del (s) if filename: f = open(str(filename), 'wb') pickle.dump(bhorbit, f) f.close() return bhorbit
def getBHMergers(simname, orbitfile=None, halofile=None, outputname=None, filename=None): if orbitfile: f = open(orbitfile, 'rb') BHorbit = pickle.load(f) f.close() if halofile: f2 = open(halofile, 'rb') BHhalo = pickle.load(f2) f2.close() if orbitfile or halofile: if not os.path.exists(orbitfile) or not os.path.exists(halofile): print "ERROR: cannot fine orbit and/or halo file" return if not os.path.exists('files.list'): print "files.list not found. generating list of output files..." getFileLists(simname) files = open("files.list", 'r') f1 = files.readlines() s = pynbody.load(f1[0].strip('\n')) munits = s['mass'].units posunits = s['x'].units velunits = s['vx'].units potunits = s['phi'].units tunits = posunits / velunits Eunits = munits * potunits files.close() if not os.path.exists('BHmerge.txt'): if outputname == None: os.system( "awk '/BHSink/ && /Merge/ && /eating/' *out* > BHmerge.txt") else: os.system("awk '/BHSink/ && /Merge/ && /eating/' *" + outputname + "* > BHmerge.txt") else: print "WARNING: BHmerge.txt already exists for this run... using that one. Please delete if you would like it to be updated." a, b, ID1, c, ID2, d, Time, e, f, kvel, g, h, Mratio = readcol.readcol( 'BHmerge.txt', twod=False) del (a, b, c, d, e, f, g, h) ID1 = np.int(ID1) ID2 = np.int(ID2) Time = np.float(Time) kvel = np.float(kvel) Mratio = np.float(Mratio) id2tmp, count = np.unique(ID2, return_counts=True) bad, = np.where(count > 1) if len(bad) > 0: print "Warning! Found a double counted merger. Fixing..." idbad = id2tmp[bad] for i in idbad: baddat, = np.where(ID2 == idbad) np.delete(ID2, baddat[0:len(ID2) - 1]) np.delete(ID1, baddat[0:len(ID2) - 1]) np.delete(Time, baddat[0:len(ID2) - 1]) np.delete(kvel, baddat[0:len(ID2) - 1]) np.delete(Mratio, baddat[0:len(ID2) - 1]) o = np.argsort(Time) Time = array.SimArray(Time[o], tunits) Time = Time.in_units('Gyr') ID1 = ID1[o] ID2 = ID2[o] kvel = kvel[o] Mratio = Mratio[o] nMergers = len(Time) print "found", nMergers, "BH-BH mergers occuring in simulation" M1 = array.SimArray(np.zeros(nMergers), 'Msol') M2 = array.SimArray(np.zeros(nMergers), 'Msol') HaloID1 = np.zeros(nMergers) HaloID2 = np.zeros(nMergers) HaloMass1 = array.SimArray(np.zeros(nMergers), 'Msol') HaloGas1 = array.SimArray(np.zeros(nMergers), 'Msol') HaloStars1 = array.SimArray(np.zeros(nMergers), 'Msol') HaloMass2 = array.SimArray(np.zeros(nMergers), 'Msol') HaloGas2 = array.SimArray(np.zeros(nMergers), 'Msol') HaloStars2 = array.SimArray(np.zeros(nMergers), 'Msol') if BHorbit or BHhalo: for i in range(nMergers): if BHorbit: no1, = np.where(BHorbit['iord'] == ID1[i]) no2, = np.where(BHorbit['iord'] == ID2[i]) to, = np.where( BHorbit['data'][no1]['Time'].in_units('Gyr') < Time[i]) if BHorbit['data'][no2]['Time'][-1].in_units('Gyr') > Time[1]: print "WARNING larger time in orbit file for BH", BHhalo[ 'iord'][no2], " Tmerge", Time[i], "Torbit", BHorbit[ 'data'][n1]['Time'].max() M1[i] = BHorbit['data'][no1]['mass'][to[-1]].in_units('Msol') M2[i] = BHorbit['data'][no2]['mass'][-1].in_units('Msol') if BHhalo: nh1, = np.where(BHhalo['iord'] == ID1[i]) nh2, = np.where(BHhalo['iord'] == ID2[i]) nonz, = np.where(BHhalo['mass'][nh2] > 0) HaloID1[i] = BHhalo['haloID'][nh1][nonz[-1]] HaloID2[i] = BHhalo['haloID'][nh2][nonz[-1]] HaloMass1[i] = BHhalo['halomass'][nh1][nonz[-1]] HaloMass2[i] = BHhalo['halomass'][nh2][nonz[-1]] HaloGas1[i] = BHhalo['halogasmass'][nh1][nonz[-1]] HaloGas2i[i] = BHhalo['halogasmass'][nh2][nonz[-1]] HaloStars1[i] = BHhalo['halostarmass'][nh1][nonz[-1]] HaloStars2[i] = BHhalo['halostarmass'][nh2][nonz[-1]] BHmerge = { 'Time': Time, 'ID1': ID1, 'ID2': ID2, 'M1': M1, 'M2': M2, 'halo1': HaloID1, 'halo2': HaloID2, 'Hmass1': HaloMass1, 'HGasMass1': HaloGas1, 'HStarMass1': HaloStars1, 'Hmass1': HaloMass2, 'HGasMass1': HaloGas2, 'HStarMass1': HaloStars2, 'kickV': kvel, 'ratio': Mratio } if filename: f = open(filename, 'wb') pickle.dump(BHmerge, f) f.close() return BHmerge
def getAccretion(simname, BHlist=[], filename=False, allData=False): if not os.path.exists('files.list'): print "files.list not found. generating list of output files..." getFileLists(simname) bhids = getBHiords(simname) files = open("files.list", 'r') f1 = files.readlines() s = pynbody.load(f1[0].strip('\n')) munits = s['mass'].units posunits = s['x'].units velunits = s['vx'].units potunits = s['phi'].units tunits = posunits / velunits Eunits = munits * potunits files.close() print "separating BH data..." acclogFile = simname + '.BHAccLog' os.system("awk -F ' ' '{print >$1}' " + acclogFile) #bhAccData = readcol.readcol(acclogFile) #bhids = np.unique(bhAccData[:,0]) if len(BHlist) > 0: matches = np.in1d(bhids, BHlist) bhAccHist = {'iord': bhids[matches], 'data': np.array([])} else: bhAccHist = {'iord': bhids, 'data': np.array([])} print "there are ", len(bhids), " BHs that have existed in this simulation" if len(BHlist) > 0: nBHs = len(BHlist) else: nBHs = len(bhids) print "getting data...." cnt = 0 for id in bhids: if len(BHlist) > 0: match, = np.where(BHlist == id) if len(match) == 0: os.system("rm " + str(np.int(id))) continue print "getting data for BH ", id bhAccData = readcol.readcol(str(np.int(id))) os.system("rm " + str(np.int(id))) bad, = np.where(bhAccData[:, 0] != id) if len(bad) > 0: print "WARNING: bad ID found in miniorbit.txt file after awk... deleting" bhAccData = np.delete(bhAccData, bad, axis=0) cnt += 1 GoodScale = True print "BH #" + str(cnt) + "/" + str(nBHs) time = bhAccData[:, 2] o = np.argsort(time) timeOrd = time[o] t1 = timeOrd[0:len(timeOrd) - 1] t2 = timeOrd[1:len(timeOrd)] bad = np.where(np.equal(t1, t2)) np.delete(o, bad) time = array.SimArray(time[o], tunits) iGasOrd = bhAccData[o, 1] MgasInit = array.SimArray(bhAccData[o, 3], munits) MbhInit = array.SimArray(bhAccData[o, 4], munits) MgasFinal = array.SimArray(bhAccData[o, 5], munits) MbhFinal = array.SimArray(bhAccData[o, 6], munits) dMgas = array.SimArray(bhAccData[o, 7], munits) dMBH = array.SimArray(bhAccData[o, 8], munits) dMneed = array.SimArray(bhAccData[o, 9], munits) scaleFac = bhAccData[o, 19] dx = array.SimArray(bhAccData[o, 10], posunits) * scaleFac dy = array.SimArray(bhAccData[o, 11], posunits) * scaleFac dz = array.SimArray(bhAccData[o, 12], posunits) * scaleFac dvx = array.SimArray(bhAccData[o, 13], velunits) dvy = array.SimArray(bhAccData[o, 14], velunits) dvz = array.SimArray(bhAccData[o, 15], velunits) Ugas = array.SimArray(bhAccData[o, 16], Eunits) fBall = array.SimArray(bhAccData[o, 17], posunits) * scaleFac tCoolOff = array.SimArray(bhAccData[o, 18], tunits) density = array.SimArray(bhAccData[o, 20], munits / posunits**3) * scaleFac**(-3) temp = array.SimArray(bhAccData[o, 21], 'K') metals = array.SimArray(bhAccData[o, 22]) if allData: datastruct = { 'time': time.in_units('Gyr'), 'Mgas': MgasInit.in_units('Msol'), 'Mbh': MbhInit.in_units('Msol'), 'MgasFinal': MgasFinal.in_units('Msol'), 'MbhFinal': MbhFinal.in_units('Msol'), 'deltaMgas': dMgas.in_units('Msol'), 'deltaM': dMBH.in_units('Msol'), 'Mneed': dMneed.in_units('Msol'), 'dx': dx.in_units('kpc'), 'dy': dy.in_units('kpc'), 'dz': dz.in_units('kpc'), 'dvx': dvx.in_units('kpc'), 'dvy': dvy.in_units('kpc'), 'dvz': dvz.in_units('kpc'), 'Ugas': Ugas, 'fBall': fBall.in_units('kpc', a=1), 'tCoolOff': tCoolOff, 'scaleFac': scaleFac, 'density': density.in_units('m_p cm**-3', a=1), 'temp': temp, 'metals': metals } else: datastruct = { 'time': time.in_units('Gyr'), 'Mgas': MgasInit.in_units('Msol'), 'Mbh': MbhInit.in_units('Msol'), 'deltaM': dMBH.in_units('Msol'), 'dx': dx.in_units('kpc', a=1), 'dy': dy.in_units('kpc', a=1), 'dz': dz.in_units('kpc', a=1), 'dvx': dvx.in_units('km s**-1', a=1), 'dvy': dvy.in_units('km s**-1', a=1), 'dvz': dvz.in_units('km s**-1', a=1), 'Ugas': Ugas, 'fBall': fBall.in_units('kpc', a=1), 'tCoolOff': tCoolOff, 'scaleFac': scaleFac, 'density': density.in_units('m_p cm**-3', a=1), 'temp': temp, 'metals': metals } bhAccHist['data'] = np.append(bhAccHist['data'], datastruct) del (s) if filename: f = open(str(filename), 'wb') pickle.dump(bhAccHist, f) f.close() return bhAccHist
def ang_mom_vec_units(snap): angmom = ang_mom_vec(snap) return array.SimArray( angmom, snap['mass'].units * snap['pos'].units * snap['vel'].units)
def render(sim, filename=None, r_band='i', g_band='v', b_band='u', r_scale=0.5, g_scale=1.0, b_scale=1.0, dynamic_range=2.0, mag_range=None, width=50, starsize=None, plot=True, axes=None, ret_im=False, clear=True, ret_range=False): ''' Make a 3-color image of stars. The colors are based on magnitudes found using stellar Marigo stellar population code. However there is no radiative transfer to account for dust. Returns: If ret_im=True, an NxNx3 array representing an RGB image **Optional keyword arguments:** *filename*: string (default: None) Filename to be written to (if a filename is specified) *r_band*: string (default: 'i') Determines which Johnston filter will go into the image red channel *g_band*: string (default: 'v') Determines which Johnston filter will go into the image green channel *b_band*: string (default: 'b') Determines which Johnston filter will go into the image blue channel *r_scale*: float (default: 0.5) The scaling of the red channel before channels are combined *g_scale*: float (default: 1.0) The scaling of the green channel before channels are combined *b_scale*: float (default: 1.0) The scaling of the blue channel before channels are combined *width*: float in kpc (default:50) Sets the size of the image field in kpc *starsize*: float in kpc (default: None) If not None, sets the maximum size of stars in the image *ret_im*: bool (default: False) if True, the NxNx3 image array is returned *ret_range*: bool (default: False) if True, the range of the image in mag arcsec^-2 is returned. *plot*: bool (default: True) if True, the image is plotted *axes*: matplotlib axes object (deault: None) if not None, the axes object to plot to *dynamic_range*: float (default: 2.0) The number of dex in luminosity over which the image brightness ranges *mag_range*: float, float (default: None) If provided, the brightest and faintest surface brightnesses in the range, in mag arcsec^-2. Takes precedence over dynamic_range. ''' if isinstance(width, str) or issubclass(width.__class__, _units.UnitBase): if isinstance(width, str): width = _units.Unit(width) width = width.in_units(sim['pos'].units, **sim.conversion_context()) if starsize is not None: smf = filt.HighPass('smooth', str(starsize) + ' kpc') sim.s[smf]['smooth'] = array.SimArray(starsize, 'kpc', sim=sim) r = image(sim.s, qty=r_band + '_lum_den', width=width, log=False, units="pc^-2", clear=False, noplot=True) * r_scale g = image(sim.s, qty=g_band + '_lum_den', width=width, log=False, units="pc^-2", clear=False, noplot=True) * g_scale b = image(sim.s, qty=b_band + '_lum_den', width=width, log=False, units="pc^-2", clear=False, noplot=True) * b_scale # convert all channels to mag arcsec^-2 r = pynbody.plot.stars.convert_to_mag_arcsec2(r) g = pynbody.plot.stars.convert_to_mag_arcsec2(g) b = pynbody.plot.stars.convert_to_mag_arcsec2(b) #r,g,b = nw_scale_rgb(r,g,b) #r,g,b = nw_arcsinh_fit(r,g,b) if mag_range is None: rgbim, mag_max = pynbody.plot.stars.combine(r, g, b, dynamic_range * 2.5) mag_min = mag_max + 2.5 * dynamic_range else: mag_max, mag_min = mag_range rgbim, mag_max = pynbody.plot.stars.combine(r, g, b, mag_min - mag_max, mag_max) if plot: if clear: plt.clf() if axes is None: axes = plt.gca() if axes: axes.imshow(rgbim[::-1, :], extent=(-width / 2, width / 2, -width / 2, width / 2)) axes.set_xlabel('x [' + str(sim.s['x'].units) + ']') axes.set_ylabel('y [' + str(sim.s['y'].units) + ']') plt.draw() if filename: plt.axis('off') plt.savefig(filename, dpi=1600, figsize=(25, 25), bbox_inches='tight') if ret_im: return rgbim if ret_range: return mag_max, mag_min