Beispiel #1
0
    def add_dif(self):
        '''Generates diffuse gas clouds and creates new dif particle data file for a galaxy.
        '''

        print('\nCREATING DIFFUSE GAS CLOUDS FOR THIS GALAXY')

        simgas = aux.load_temp_file(gal_ob=self.gal_ob, sim_type='gas')

        # TEST
        # simgas = simgas[0:1000]

        # Start new dataframe with only the diffuse gas
        difgas = simgas.copy()
        difgas['m'] = simgas['m'].values * (1. - simgas['f_H21'].values)
        print('Total gas mass in galaxy: %.2e Msun' % (sum(simgas['m'])))
        print('Diffuse gas mass in galaxy: %.2e Msun' % (sum(difgas['m'])))
        print('in percent: %.2f %%' %
              (sum(difgas['m']) / sum(simgas['m']) * 100.))

        # Set radius of diffuse gas clouds
        difgas['R'] = difgas['h']

        # Calculate density of diffuse gas clouds [Hydrogen atoms per cm^3]
        difgas['nH'] = 0.75 * np.array(
            difgas['m'], dtype=np.float64) / (4 / 3. * np.pi * np.array(
                difgas['R'], dtype=np.float64)**3.) * Msun / mH / kpc2cm**3

        # Set nH and R to zero when there is no mass
        mask = difgas.m == 0
        difgas.loc[mask, 'nH'] = 0
        difgas.loc[mask, 'R'] = 0

        # Store new difgas file
        aux.save_temp_file(difgas, gal_ob=self.gal_ob, ISM_phase='dif')
Beispiel #2
0
    def create_dc(self, ISM_dc_phase):
        """Calculates the datacube of a specific ISM_phase

        Parameters
        ----------
        ISM_dc_phase: str
            The datacube ISM phase

        Examples
        --------
        >>> gal_ob.datacube.create_dc('GMC')

        """

        if ISM_dc_phase == 'GMC':
            dataframe = self.gal_ob.particle_data.get_raw_data(
                data='ISM')['GMC']
        if ISM_dc_phase in ['DNG', 'DIG']:
            dataframe = self.gal_ob.particle_data.get_raw_data(
                data='ISM')['dif']

        dc, dc_sum = aux.mk_datacube(self.gal_ob,
                                     dataframe,
                                     ISM_dc_phase=ISM_dc_phase)

        # Fix units if looking at line emission
        if 'L_' in target:
            dc_Lsun = np.nan_to_num(dc)
            print('Max in Lsun: %.2e ' % np.max(dc_Lsun))
            freq = params[target.replace('L_',
                                         'f_')]  #Lsunkms, zred, d_L, nu_rest
            dc = aux.solLum2Jy(dc_Lsun / v_res, self.gal_ob.zred,
                               self.gal_ob.lum_dist, freq)
            print('Max in Jy: %.2e ' % np.max(dc))

        # Save what
        # aux.save_temp_file(dataframe,gal_ob=self.gal_ob,ISM_dc_phase=ISM_dc_phase)

        # Save datacube
        dc = pd.DataFrame({'data': [dc]})
        # dc.metadata             =   {'dc_sum':dc_sum}

        # test convert back to Lsun
        # L = aux.Jykm_s_to_L_sun(dc_Jy*v_res, freq, self.gal_ob.zred,self.gal_ob.lum_dist)
        aux.save_temp_file(dc,
                           gal_ob=self.gal_ob,
                           target=target,
                           ISM_dc_phase=ISM_dc_phase)
Beispiel #3
0
    def interpolate_dif(self):
        """Adds info from cloud model runs to diffuse gas clouds
        """
        print('\nADDING EMISSION INFO TO DIFFUSE GAS IN THIS GALAXY')

        difgas = aux.load_temp_file(gal_ob=self.gal_ob, ISM_phase='dif')

        # Get diffuse background FUV to use for this galaxy (OLD WAY)
        self.UV_str = aux.get_UV_str(z1, self.SFRsd)

        # Load cloudy model grid:
        cloudy_grid_param = pd.read_pickle(d_cloudy_models + 'difgrid_' +
                                           self.UV_str + 'UV' + ext_DIFFUSE +
                                           '_' + z1 + '.param')
        cloudy_grid = pd.read_pickle(d_cloudy_models + 'difgrid_' +
                                     self.UV_str + 'UV' + ext_DIFFUSE + '_' +
                                     z1 + '_em.models')
        difgas_new = aux.interpolate_in_dif_models(difgas, cloudy_grid_param,
                                                   cloudy_grid)

        aux.save_temp_file(difgas_new, gal_ob=self.gal_ob, ISM_phase='dif')
Beispiel #4
0
    def interpolate_GMCs(self):
        """Adds info from cloud model runs to GMCs
        """
        print('\nADDING EMISSION INFO TO GMCs IN THIS GALAXY')

        GMCgas = aux.load_temp_file(gal_ob=self.gal_ob,
                                    ISM_phase='GMC',
                                    verbose=True)

        # Load cloudy model grid:
        cloudy_grid_param = pd.read_pickle(d_cloudy_models + 'GMCgrid' +
                                           ext_DENSE + '_' + z1 + '.param')

        cloudy_grid_param['ms'] = cloudy_grid_param['Mgmcs']
        cloudy_grid = pd.read_pickle(d_cloudy_models + 'GMCgrid' + ext_DENSE +
                                     '_' + z1 + '_em.models')

        # print(cloudy_grid_param['Mgmcs'])
        # print(cloudy_grid.shape)

        GMCgas_new = aux.interpolate_in_GMC_models(GMCgas, cloudy_grid_param,
                                                   cloudy_grid)

        aux.save_temp_file(GMCgas_new, gal_ob=self.gal_ob, ISM_phase='GMC')
Beispiel #5
0
    def __create_file(self, **kwargs):

        # create empty container for global_results
        GR = {}

        extracted_gals = pd.read_pickle(d_temp +
                                        'galaxies/%s_extracted_gals' % z1)

        zreds, galnames = extracted_gals['zreds_unsorted'], extracted_gals[
            'galnames_unsorted']
        GR['galnames'] = galnames
        GR['zreds'] = zreds
        GR['N_gal'] = len(galnames)

        # convert DF to DataFrame
        GR = pd.DataFrame(GR)

        # add un-populated targets to DF
        targets = [
            'R_gal', 'M_gas', 'M_star', 'M_GMC', 'M_dense', 'M_dm', 'SFR',
            'SFRsd', 'Zsfr'
        ]
        N_gal = GR.shape[0]
        for target in targets:
            GR[target] = np.zeros(N_gal)

        # collect sim data
        for i, zred, galname in zip(range(N_gal), zreds, galnames):

            # get data
            gal_ob = dict(galname=galname, zred=zred,
                          gal_index=i)  # dummy gal object
            simgas = aux.load_temp_file(gal_ob=gal_ob,
                                        sim_type='gas',
                                        gal_ob_present=True)
            simstar = aux.load_temp_file(gal_ob=gal_ob,
                                         sim_type='star',
                                         gal_ob_present=True)
            simdm = aux.load_temp_file(gal_ob=gal_ob,
                                       sim_type='dm',
                                       gal_ob_present=True)
            # check if f_H21 is there, if not, make a copy so the rest of the code works (temporary fix):
            if 'f_H21' not in simgas.keys():
                simgas['f_H21'] = simgas['f_H2'].values
                gal_ob = dict(galname=galname, zred=zred,
                              gal_index=i + 1)  # dummy gal object
                aux.save_temp_file(simgas,
                                   gal_ob=gal_ob,
                                   sim_type='gas',
                                   gal_ob_present=True)

            # get radii
            r_gas = np.sqrt(
                sum([simgas[x].values**2. for x in ['x', 'y', 'z']]))
            r_star = np.sqrt(
                sum([simstar[x].values**2. for x in ['x', 'y', 'z']]))

            # set R_gal
            rmax = np.max(r_gas)
            GR.at[i, 'R_gal'] = rmax

            # set M_*
            # mask    =   r_star < rmax
            # age     =   simstar['age'].values[mask]
            # m_stars =   simstar['m'].values[mask]
            age = simstar['age'].values
            m_stars = simstar['m'].values
            GR.at[i, 'M_star'] = np.sum(m_stars)
            GR.at[i, 'M_dm'] = np.sum(simdm['m'].values)
            GR.at[i, 'M_gas'] = np.sum(simgas['m'].values)
            GR.at[i, 'f_dense'] = (np.sum(
                simgas['m'].values * simgas['f_H21'].values)) / np.sum(
                    simgas['m'].values)

            # ratios and metalicities
            if np.sum(m_stars) <= 0.5:
                print(i)
                import pdb
                pdb.set_trace()

            GR.at[i, 'mw_age'] = (np.sum(age * m_stars) / np.sum(m_stars)
                                  )  # mass-weighted age
            GR.at[i, 'SFR'] = np.sum(m_stars[age < 100.]) / 100e6
            GR.at[i, 'SFRsd'] = GR.SFR[i] / (np.pi * rmax**2.)
            GR.at[i, 'Zsfr'] = np.sum(
                simgas['Z'].values *
                (simgas['SFR'].values + 1.e-8)) / np.sum(simgas['SFR'].values +
                                                         1.e-8)
        for attr in ['lum_dist', 'M_dense', 'M_GMC', 'M_dif', 'Zmw']:
            GR = self.__set_attr(GR, attr)
        for line in lines:
            GR = self.__set_attr(GR, 'L_' + line)

        # # set M_tot
        # DF['M_tot'] =   DF['M_gas'].values + DF['M_star'].values + DF['M_dm'].values

        # Only consider galaxies with a SFR > 0
        GR = GR[GR['SFR'] > 0].reset_index(drop=True)

        # If z=0, only consider low-z galaxies (out to ~ 100 Mpc)
        if z1 == 'z0': GR = GR[GR['zreds'] < 0.04].reset_index(drop=True)

        # sort DF by stellar mass
        GR = GR.sort_values('M_star').reset_index(drop=True)
        # Make sure we only extract a sample of size nGal
        # GR  =   GR[0:nGal]

        # save DF of global results
        filename = self.__get_file_location()
        GR.to_pickle(filename)

        return GR
Beispiel #6
0
    def add_GMCs(self):
        '''Generates GMCs and creates new GMC particle data file for a galaxy.
        '''

        print('\nSPLITTING DENSE GAS INTO GMCs FOR THIS GALAXY')

        simgas = aux.load_temp_file(gal_ob=self.gal_ob,
                                    sim_type='gas',
                                    verbose=True)

        # Checking that the sim gas data has what we need
        if 'P_ext' not in simgas.keys():
            print('\nExternal pressure not calculated, doing so now')
            self.add_P_ext()
        if 'FUV' not in simgas.keys():
            print('\nFUV radiation field not calculated, doing so now')
            self.add_FUV()

        simgas              =   simgas[['Z','a_C','a_Ca','a_Fe','a_He','a_Mg','a_N','a_Ne','a_O','a_S','a_Si','f_H21','f_HI1','f_neu','m','h',\
                                'vx','vy','vz','x','y','z','FUV','CR','P_ext','surf_gas','surf_star','sigma_gas','sigma_star','vel_disp_gas']]

        # TEST
        # simgas = simgas[0:100]

        # Neutral (dense) gas mass
        Mneu = simgas['m'].values * simgas['f_H21'].values

        print('Number of particles with enough dense mass: %s' %
              (len(simgas.loc[Mneu > 1e4]['m'])))
        print('Out of: %s' % (len(simgas)))
        print('Dense gas mass fraction out of total ISM mass: %s %%' %
              (np.sum(Mneu) / np.sum(simgas['m']) * 100.))

        if len(Mneu[Mneu > 1e4]) == 0:
            print(
                " No dense gas w/ mass > 10^4 Msun. Skipping subgrid for this galaxy."
            )
            pdb.set_trace()

        print('Min and max particle dense gas mass: %s Msun' %
              (np.min(Mneu[Mneu > 0])) + ' ' + str(np.max(Mneu)))
        print('Throwing away this much gas mass: %s Msun' %
              (np.sum(Mneu[Mneu < 1e4])))
        print('In percent: %s %%' % (np.sum(Mneu[Mneu < 1e4]) / np.sum(Mneu)))

        # Create mass spectrum (probability function = dN/dM normalized)
        b = 1.8  # MW powerlaw slope [Blitz+07]
        if ext_DENSE == '_b3p0':
            b = 3.0  # outer MW and M33 powerlaw slope [Rosolowsky+05, Blitz+07]
        if ext_DENSE == '_b1p5':
            b = 1.5  # inner MW powerlaw slope [Rosolowsky+05, Blitz+07]
        print('Powerlaw slope for mass spectrum (beta) used is %s' % b)
        Mmin = 1.e4  # min mass of GMC
        Mmax = np.max(Mneu)  # max mass of GMC
        tol = Mmin  # precision in reaching total mass
        nn = 100  # max draw of masses in each run
        n_elements = simgas.size
        simgas = simgas[Mneu > 1e4]  # Cut out those with masses < 1e4 !!
        Mneu = Mneu[Mneu > 1e4]
        h = simgas['h'].values
        simgas.index = range(0, len(simgas))

        if N_cores == 1:
            print('(Not using multiprocessing - 1 core in use)')
            f1, Mgmc, newx, newy, newz = aux.GMC_generator(
                np.arange(0, len(simgas)), Mneu, h, Mmin, Mmax, b, tol, nn,
                N_cores)
            GMCs = [f1, Mgmc, newx, newy, newz]
            print('(Done!)')
            print('Append results to new dataframe')

            GMCgas = pd.DataFrame()
            Mgmc = np.array([])
            newx = np.array([])
            newy = np.array([])
            newz = np.array([])
            part = 0.1

            for i in range(0, len(simgas)):
                Mgmc = np.append(Mgmc, GMCs[1][i])  # appending mass
                newx = np.append(newx, simgas.loc[i]['x'] +
                                 GMCs[2][i])  # appending x position
                newy = np.append(newy, simgas.loc[i]['y'] +
                                 GMCs[3][i])  # appending y position
                newz = np.append(newz, simgas.loc[i]['z'] +
                                 GMCs[4][i])  # appending z position
                for ii in range(0, int(GMCs[0][i])):
                    # For each GMC created, duplicate remaining sim gas particle properties
                    GMCgas = pd.DataFrame.append(GMCgas,
                                                 simgas.loc[i],
                                                 ignore_index=True)
                if 1. * i / len(simgas) > part:
                    percent = np.floor(1. * i / len(simgas) * 10.) * 10.
                    print('%s %% done!' % percent)
                    part = percent / 100. + 0.1

            try:
                GMCgas['m'] = Mgmc
            except:
                print(Mgmc)
                pdb.set_trace()

        if N_cores > 1:

            print('(Multiprocessing starting up! %s cores in use)' % N_cores)
            pool = mp.Pool(processes=N_cores)
            np.random.seed(
                len(simgas)
            )  # so we don't end up with the same random numbers for every galaxy

            results = [
                pool.apply_async(aux.GMC_generator, (
                    [i],
                    Mneu,
                    h,
                    Mmin,
                    Mmax,
                    b,
                    tol,
                    nn,
                    N_cores,
                )) for i in range(0, len(simgas))
            ]
            pool.close()
            pool.join()
            GMCs = [p.get() for p in results]
            GMCs.sort(key=lambda x: x[0])

            print('(Multiprocessing done!)')

            print('Append results to new dataframe')

            GMCgas = pd.DataFrame()
            Mgmc = np.array([])
            newx = np.array([])
            newy = np.array([])
            newz = np.array([])
            part = 0.1

            for i in range(0, len(simgas)):
                # For each sim gas particle with enough dense gas, add GMCs created
                # pdb.set_trace()
                Mgmc = np.append(Mgmc, GMCs[i][2])  # appending mass
                newx = np.append(newx, simgas.loc[i]['x'] +
                                 GMCs[i][3])  # appending x position
                newy = np.append(newy, simgas.loc[i]['y'] +
                                 GMCs[i][4])  # appending y position
                newz = np.append(newz, simgas.loc[i]['z'] +
                                 GMCs[i][5])  # appending z position

                for i1 in range(0, int(GMCs[i][1])):
                    # For each GMC created, duplicate remaining sim gas particle properties
                    GMCgas = pd.DataFrame.append(GMCgas,
                                                 simgas.loc[i],
                                                 ignore_index=True)
                # Keep track of GMCs added

                if 1. * i / len(simgas) > part:
                    percent = np.floor(1. * i / len(simgas) * 10.) * 10.
                    print('%s %% done!' % percent)
                    part = percent / 100. + 0.1
            try:
                GMCgas['m'] = Mgmc
            except:
                print(Mgmc)
                pdb.set_trace()

        GMCgas['x'] = newx
        GMCgas['y'] = newy
        GMCgas['z'] = newz
        GMCgas['Rgmc'] = (GMCgas['m'] / 290.0)**(1.0 / 2.0)

        print('Mass of all GMCs created: %.2e - should not exceed:' %
              np.sum(GMCgas['m']))
        print('Total neutral gas: %.2e ' % np.sum(Mneu))
        print(np.min(GMCgas['Rgmc']), np.max(GMCgas['Rgmc']))

        print(str(len(GMCgas)) + ' GMCs created!')

        # Store new GMCgas file
        # GMCgas.metadata     =   {'beta':b}
        aux.save_temp_file(GMCgas, gal_ob=self.gal_ob, ISM_phase='GMC')
Beispiel #7
0
    def add_P_ext(self):
        '''Adds external pressure to galaxy and stores gas/star sim particle data files again with the new information.
        '''

        print('\nADDING EXTERNAL PRESSURE FIELD TO GALAXY')

        # Make global variables for Pfunc function
        global simgas, simgas1, simstar, m_gas, m_star

        simgas = aux.load_temp_file(gal_ob=self.gal_ob, sim_type='gas')
        simstar = aux.load_temp_file(gal_ob=self.gal_ob, sim_type='star')

        # TEST
        # simgas = simgas[0:1000]
        # simstar = simstar[0:1000]

        # Extract star forming gas only:
        simgas1 = simgas.copy()
        simgas1 = simgas1[simgas1['SFR'] > 0].reset_index()

        # Extract gas and star masses
        m_gas, m_star = simgas1['m'].values, simstar['m'].values

        print('(Multiprocessing starting up! %s cores in use)' % N_cores)
        pool = mp.Pool(
            processes=N_cores)  # 8 processors on my Mac Pro, 16 on Betty
        results = [
            pool.apply_async(aux.Pfunc,
                             args=(
                                 i,
                                 simgas1,
                                 simgas,
                                 simstar,
                                 m_gas,
                                 m_star,
                             )) for i in range(0, len(simgas))
        ]  #len(simgas)
        pool.close()
        pool.join()

        # sort results since apply_async doesn't return results in order
        res = [p.get() for p in results]
        res.sort(key=lambda x: x[0])
        print('(Multiprocessing done!)')

        # Store pressure,velocity dispersion and surface densities
        for i, key in enumerate([
                'P_ext', 'surf_gas', 'surf_star', 'sigma_gas', 'sigma_star',
                'vel_disp_gas'
        ]):

            simgas[key] = [res[_][i + 1] for _ in range(len(res))]
            if key == 'P_ext':
                simgas[key] = simgas[
                    key] * Msun**2 / kpc2m**4 / kB / 1e6  # K/cm^3

        # Store new simgas and simstar files
        aux.save_temp_file(simgas,
                           gal_ob=self.gal_ob,
                           sim_type='gas',
                           subgrid=True)
        aux.save_temp_file(simstar,
                           gal_ob=self.gal_ob,
                           sim_type='star',
                           subgrid=True)

        del simgas, simgas1, simstar, m_gas, m_star

        setattr(self, 'P_ext_added', True)
Beispiel #8
0
    def add_FUV(self):
        '''Adds FUV radiation field to galaxy and stores gas/star sim particle data files again with the new information.
        '''

        print('\nADDING FUV RADIATION FIELD TO GALAXY')

        global simgas, simstar, L_FUV

        simgas = aux.load_temp_file(gal_ob=self.gal_ob, sim_type='gas')
        simstar = aux.load_temp_file(gal_ob=self.gal_ob, sim_type='star')

        # TEST
        # simgas = simgas[0:1000]
        # simstar = simstar[0:1000]

        # Get FUV grid results from starburst99
        Zs, ages, L_FUV_grid = aux.get_FUV_grid_results(z1)

        # Get stellar metallicity and FUV from simulation
        Zsim = simstar.copy()['Z']
        agesim = simstar.copy()['age']
        agesim[agesim >
               1e4] = 1e4  # since sb99 cannot handle anything older than 10Gyr

        # Calculate FUV luminosity of each stellar particle [ergs/s]
        part = 0.1
        L_FUV = np.zeros(len(simstar))
        for i in range(0, len(simstar)):
            f = interp2d(np.log10(Zs), np.log10(ages), np.log10(L_FUV_grid))
            L_FUV[i] = simstar.loc[i]['m'] / 1e5 * 10.**f(
                np.log10(Zsim[i]), np.log10(agesim[i]))
            if np.isnan(L_FUV[i]) > 0: pdb.set_trace()
            if 1. * i / len(simstar) > part:
                print(int(part * 100), ' % done!')
                part = part + 0.1
        simstar['L_FUV'] = L_FUV

        print('Minimum FUV luminosity: %s Lsun' % (np.min(L_FUV)))
        print('Maximum FUV luminosity: %s Lsun' % (np.max(L_FUV)))
        if np.min(L_FUV) < 0:
            print(
                'SB99 grid not sufficient: Some FUV stellar luminosity is negative'
            )
            pdb.set_trac()

        # Find FUV flux at gas particle positions
        F_FUV = np.zeros(len(simgas))
        print('(Multiprocessing starting up! %s cores in use)' % N_cores)
        pool = mp.Pool(
            processes=N_cores)  # 8 processors on my Mac Pro, 16 on Betty
        results = [
            pool.apply_async(aux.FUVfunc, args=(
                i,
                simstar,
                simgas,
                L_FUV,
            )) for i in range(0, len(simgas))
        ]  #len(simgas)
        pool.close()
        pool.join()

        res = [p.get() for p in results]
        res.sort(key=lambda x: x[0])
        F_FUV = [res[_][1] for _ in range(len(res))]
        print('(Multiprocessing done!)')

        # Store FUV field in local FUV field units
        F_FUV_norm = np.array(F_FUV) / (kpc2cm**2 * FUV_ISM)
        simgas['FUV'] = F_FUV_norm

        # Store CR intensity in local CR intensity units
        simgas['CR'] = F_FUV_norm * CR_ISM

        print('Minimum FUV flux: %s x ISM value' % (np.min(F_FUV_norm)))
        print('Maximum FUV flux: %s x ISM value' % (np.max(F_FUV_norm)))

        # Store new simgas and simstar files
        aux.save_temp_file(simgas,
                           gal_ob=self.gal_ob,
                           sim_type='gas',
                           subgrid=True)
        aux.save_temp_file(simstar,
                           gal_ob=self.gal_ob,
                           sim_type='star',
                           subgrid=True)

        del simgas, simstar, L_FUV

        setattr(self, 'FUV_added', True)