Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
	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)
Beispiel #6
0
	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)