def _find_los(points_dset_source, camera, nbSample): r""" Find the line of sight axis which is along the angular momentum of the gas inside the camera box Parameters ---------- points_dset_source : :ref:`PointDataSource` fields "vel", "rho" and "size" needed camera : pymses camera box definition restriction nbSample : int (default=2000) not working yet : may speed up if random sampling ? """ filtered_points_dset_source = RegionFilter(camera.get_bounding_box(), points_dset_source) filtered_points_dset = filtered_points_dset_source.flatten( ) # multiprocessing data reading and filtering d = filtered_points_dset.fields["rho"] * ( filtered_points_dset.fields["size"]**3) v = filtered_points_dset["vel"] JJ = np.zeros_like(v) p = d[:, np.newaxis] * v JJ[:] = np.cross((filtered_points_dset.points[:] - camera.center), p[:]) J = np.sum(JJ, axis=0) result_vect = J / sum(J**2) result_vect = result_vect / np.linalg.norm(result_vect, 2) return result_vect
def amr2cell(ro=None, list_var=None, log_sfera=False, camera_in={}, verbose=False): """ log_sfera: Boolean True for sphere """ assert ro != None assert list_var != None from pymses.utils import regions from pymses.filters import RegionFilter, CellsToPoints amr = ro.amr_source(list_var) center = camera_in['center'] radius = camera_in['region_size'][0] if (log_sfera): regione_sp = regions.Sphere(center, radius) else: sinistra = np.copy(center) - radius destra = np.copy(center) + radius regione_sp = regions.Box((sinistra, destra)) if (verbose): print 'Extracting cells' if (log_sfera): print ' getting a sphere' print ' center:', center print ' radius:', radius else: print ' getting a box' print ' center:', center print ' size :', radius print ' left :', sinistra print ' right :', destra # cut the region amr = RegionFilter(regione_sp, amr) amr = CellsToPoints(amr) celle = amr.flatten() amr = None return celle
def _find_galaxy_axis(points_dset_source, camera, nbSample): ''' If a galaxy disk is centered in the camera box, this function should return a galaxy disk othogonal axis. from seren3.utils.camera_utils import find_galaxy_axis Parameters ---------- points_dset_source : :ref:`PointDataSource` fields "rho" and "size" needed camera : pymses camera, the galaxy's center has to fit the camera's center nbSample : int number of max massive points to use to compute the axis through cross product ''' filtered_points_dset_source = RegionFilter(camera.get_bounding_box(), points_dset_source) filtered_points_dset = filtered_points_dset_source.flatten( ) # multiprocessing data reading and filtering region_filtered_mesh_mass = filtered_points_dset.fields["rho"] * ( filtered_points_dset.fields["size"]**3) argsort = np.argsort(region_filtered_mesh_mass) center = camera.center nbSample = min(nbSample, argsort.size / 2 - 1) result_vect = np.array([0., 0., 0.]) for i in range(nbSample): index1 = argsort[-2 * i] index2 = argsort[-2 * i - 1] vect1 = filtered_points_dset.points[index1] - center vect2 = filtered_points_dset.points[index2] - center vect = np.cross(vect1, vect2) sign = np.dot(vect, [0., 0., 1.]) if sign < 0: vect = -vect result_vect = result_vect + vect * (region_filtered_mesh_mass[index1] + region_filtered_mesh_mass[index2]) * \ np.linalg.norm((vect1-vect2),2) result_vect = result_vect / np.linalg.norm(result_vect, 2) return result_vect
def _find_center_of_mass(points_dset_source, camera, nbSample): r""" Find the center of mass in the camera box Parameters ---------- points_dset_source : :ref:`PointDataSource` fields "rho" and "size" needed camera : pymses camera box definition restriction nbSample : int (default=2000) not working yet : may speed up if random sampling ? """ filtered_points_dset_source = RegionFilter(camera.get_bounding_box(), points_dset_source) filtered_points_dset = filtered_points_dset_source.flatten( ) # multiprocessing data reading and filtering d = filtered_points_dset.fields["rho"] * ( filtered_points_dset.fields["size"]**3) mass = np.sum(d) cm = np.sum(d[:, np.newaxis] * filtered_points_dset.points, axis=0) / mass return cm
def mstar_halomass_tree(self, tree, ds): snapshot = self._snapshot ro = snapshot.raw_snapshot() parts = ro.particle_source(["mass", "epoch"]) amr = ro.amr_source(['rho']) #Figure out the smallest possible cell size in code units boxlen = ro.info['boxlen'] lmax = ro.info['levelmax'] min_dx = boxlen/float(2**(lmax)) offset = tree.get_offset() snap_num = self._snapshot.output_number() - offset halos = tree.sub_catalogue('snap_num', snap_num) #idx = np.where(tree._tree[:]['snap_num'] == self._snapshot.output_number()-30)[0] #halos = tree[idx] # Is this right? print 'Loaded halos have snap_num:', halos[1]['snap_num'] mstar = [] mhalo = [] i = 1 for halo in halos: #Check if distinct halo if not halo['pid'].value == -1: print 'Halo %d skipped: PID = %d'%(halo['id'].value, halo['pid'].value) continue #Unit conversion cen = halo['pos'] cen = ds.arr(cen.value, cen.unit) r = halo['Rvir'] r = ds.arr(r.value, r.unit) #Create the sphere cen = cen.in_units('code_length').value r = r.in_units('code_length').value r_amr = float(r) #If the halo radius is smaller than the min cell size, #we need to try and approximate the masses enclosed. #Not sure how correct this is... factor = 1 if r < min_dx: r_amr += min_dx vol_halo = (4./3.)*np.pi*r**3 vol_cell = (4./3.)*np.pi*r_amr**3 factor = vol_halo/vol_cell #Define the regions region_part = Sphere(cen, r) region_amr = Sphere(cen, r_amr) #Filter the particles filt_parts = RegionFilter(region_part, parts) part_source = filt_parts.flatten() dm = np.where(part_source['epoch'] == 0)[0] stars = np.where(part_source['epoch'] != 0)[0] part_mass = part_source['mass']*ro.info['unit_mass'].express(C.Msun) if len(part_mass[dm]) < 50: print 'Discarding halo with less than 200 particles. Mvir=%e'%halo['Mvir'].value continue #Filter the AMR data filt_amr = RegionFilter(region_amr, amr) cell_source = CellsToPoints(filt_amr) cells = cell_source.flatten() rho = cells['rho']*ro.info['unit_density'].express(C.Msun/C.kpc**3) vol = (cells.get_sizes()*ro.info['unit_length'].express(C.kpc))**3 cell_mass = rho*vol #Compute the total mass enclosed gas_mass = np.sum(cell_mass)*factor # Multiply by factor incase we had to inflate the sphere stellar_mass = np.sum(part_mass[stars]) particle_mass = np.sum(part_mass) total_mass = gas_mass + particle_mass mstar.append(stellar_mass) mhalo.append(total_mass) i+=1 print i #print i if(config.verbose and (i%100)==0): print 'Processed %d halos...'%i return np.array(mstar), np.array(mhalo)
def fgas_halomass(self, halos=None): snapshot = self._snapshot ro = snapshot.raw_snapshot() amr = ro.amr_source(['rho']) parts = ro.particle_source(["mass"]) #Figure out the smallest possible cell size in code units boxlen = ro.info['boxlen'] lmax = ro.info['levelmax'] min_dx = boxlen/float(2**(lmax)) if config.verbose: print 'min_dx=', min_dx if (halos == None): halos = snapshot.halos() if config.verbose: print 'Processing %d halos'%len(halos) fgas = [] mhalo = [] #z = self._snapshot.current_redshift() #a = 1./(1.+z) i = 0 for halo in halos: if halo['num_p'] < 150: break #if tree: #Find this halo and count number of progenitors. #If too high, skip (frequent mergers -> tidal stripping) #idx_tree_halo = (tree._tree[:]['orig_halo_id'] == halo['id'].value) &\ # (tree._tree[:]['snap_num'] == snapshot.rockstar_output_number()) #print idx_tree_halo #tree_halo = tree._tree[idx_tree_halo] #assert(len(tree_halo)==1) #all_halos = [] #tree.find_progs(np.array([tree_halo]), all_halos) #num_progs = len(all_halos) #print 'Halo %d has %d progenitors'%(halo['id'], num_progs) #if num_progs > 150: continue #Create the sphere cen = halo['pos'].in_units('code_length').value r = halo['Rvir'].in_units('code_length').value r_amr = float(r) #If the halo radius is smaller than the min cell size, #we need to try and approximate the masses enclosed. #Not sure how correct this is... factor = 1 if r < min_dx: r_amr += min_dx vol_halo = (4./3.)*np.pi*r**3 vol_cell = (4./3.)*np.pi*r_amr**3 factor = vol_halo/vol_cell #Define the regions region_part = Sphere(cen, r) region_amr = Sphere(cen, r_amr) #Filter the particles filt_parts = RegionFilter(region_part, parts) part_source = filt_parts.flatten() part_mass = part_source['mass']*ro.info['unit_mass'].express(C.Msun) #Filter the AMR data filt_amr = RegionFilter(region_amr, amr) cell_source = CellsToPoints(filt_amr) cells = cell_source.flatten() rho = cells['rho']*ro.info['unit_density'].express(C.Msun/C.kpc**3) vol = (cells.get_sizes()*ro.info['unit_length'].express(C.kpc))**3 cell_mass = rho*vol #Compute the total mass enclosed gas_mass = np.sum(cell_mass)*factor # Multiply by factor incase we had to inflate the sphere particle_mass = np.sum(part_mass) total_mass = gas_mass + particle_mass fgas.append(gas_mass/total_mass) mhalo.append(total_mass) i+=1 #print i if(config.verbose and (i%100)==0): print 'Processes %d halos...'%i return np.array(fgas), np.array(mhalo)