Beispiel #1
0
    def add_Z_map(self, **kwargs):
        """Adds metallicity map as numpy array to particle data object, if not stored already in sigame/temp/maps/metallicity/.
        """

        # handle default args and kwargs
        args = dict(ow=False)
        args = aux.update_dictionary(args, kwargs)
        for key in args:
            exec(key + '=args[key]')

        for key in args:
            exec(key + '=args[key]')
        file_location = aux.get_file_location(gal_ob=self.gal_ob, map_type='Z')
        if os.path.exists(file_location):
            print('Particle data object already has Z map - loading')
            if kwargs['ow'] == True:
                Z_map = self.get_Z_map(**kwargs)
            print('aa')
            setattr(
                self, 'Z_map',
                aux.load_temp_file(gal_ob=self.gal_ob,
                                   map_type='Z')['data'][0])
        else:
            print(
                'Z map not stored for this particle data object, creating it. '
            )
            Z_map = self.get_Z_map(**kwargs)
            setattr(self, 'Z_map', Z_map)
Beispiel #2
0
    def get_total_sum(self, **kwargs):
        """Returns total value of datacube for all datacube ISM phases in dictionary.
        """

        # handle default values and kwargs
        args = dict(target='L_CII', all_phases=False, test=False)
        args = aux.update_dictionary(args, kwargs)
        for key in args:
            exec(key + '=args[key]')

        tot_line_lum = {}
        for i, ISM_dc_phase in enumerate(ISM_dc_phases):
            dc_i = self.get_dc(ISM_dc_phase=ISM_dc_phase, **kwargs)
            if 'L_' in target:
                mom0 = dc_i * v_res  # Jy * km/s
                freq = params[kwargs['target'].replace('L_', 'f_')]
                mom0 = aux.Jykm_s_to_L_sun(mom0, freq, self.gal_ob.zred,
                                           self.gal_ob.lum_dist)  # Lsun
                # L = aux.Jykm_s_to_L_sun(dc_Jy*v_res, freq, self.gal_ob.zred,self.gal_ob.lum_dist)
                tot = np.sum(mom0)
            else:
                tot = np.sum(dc_i)
            tot_line_lum[ISM_dc_phase] = tot

        if all_phases:
            tot_line_lum = sum(tot_line_lum.values())

        return tot_line_lum
Beispiel #3
0
    def plot_map(self, **kwargs):
        ''' Creates map of surface densities (or sum) of some parameters in sim or ISM data.


        '''

        # handle default values and kwargs
        args = dict(quan='m',
                    ISM_phase='',
                    sim_type='',
                    grid_length=100,
                    x_res=0.5,
                    get_sum=False)
        args = aux.update_dictionary(args, kwargs)
        for key in args:
            exec(key + '=args[key]')

        map_array = self.get_map(**args)
        x, y = np.meshgrid(map_array['X'], map_array['Y'])

        if quan == 'SFR': lab = getlabel('SFR')

        plot.simple_plot(figsize=(8, 8),plot_margin=0.15,xr=[-R_max,R_max],yr=[-R_max,R_max],\
            x1=x,y1=y,col1=map_array['Z'],\
            colorbar1=True,lab_colorbar1=lab,\
            aspect='equal',\
            contour_type1='mesh',nlev1=100,xlab='x [kpc]',ylab='y [kpc]',title='G%s' % (self.gal_ob.gal_index+1),\
            textfs=9,textcol='white')
Beispiel #4
0
    def get_dc(self, **kwargs):
        """Returns one datacube as numpy array.
        """

        # handle default values and kwargs
        args = dict(ISM_dc_phase='', target='')
        args = aux.update_dictionary(args, kwargs)
        for key in args:
            exec(key + '=args[key]')

        if ISM_dc_phase in ISM_dc_phases:
            return self.__get_dc_phase(**args)
        else:
            return self.__get_dc_summed(**args)
Beispiel #5
0
    def get_data(self, **kwargs):
        """Returns **rotated** particle data as dataframe.

        Parameters
        ----------
        particle_name : str
            Name of particles, can be ['gas','star','dm','GMC','dif'], default: 'GMC'

        """

        # handle default values and kwargs
        args = dict(particle_name='GMC')
        args = aux.update_dictionary(args, kwargs)

        if args['particle_name'] in ['gas', 'star', 'dm']: args['data'] = 'sim'
        if args['particle_name'] in ['GMC', 'dif']: args['data'] = 'ISM'

        # get raw data
        data = self.get_raw_data(**args)[args['particle_name']]

        # get empty arrays for rotated positions and velocities
        size = data.shape[0]
        X = np.zeros((size, 3))
        V = np.zeros_like(X)

        # populate X and V with unrotated values
        for i, x in enumerate(['x', 'y', 'z']):
            X[:, i] = data[x].values
            V[:, i] = data['v' + x].values

        # rotate X and Y
        X = self.__get_rotated_matrix(X)
        V = self.__get_rotated_matrix(V)

        # update data with rotated values
        for i, x in enumerate(['x', 'y', 'z']):
            data[x] = X[:, i]
            data['v' + x] = V[:, i]

        # add radius and speed columns
        data['radius'] = self.__get_magnitudes(X)
        data['speed'] = self.__get_magnitudes(V)

        return data
Beispiel #6
0
    def print_galaxy_properties(self, **kwargs):

        args = dict(gal_index=0)
        args = aux.update_dictionary(args, kwargs)
        for key, val in args.items():
            exec(key + '=val')

        print('\nProperties of Galaxy number %s, %s, at redshift %s' %
              (gal_index + 1, self.galnames[gal_index], self.zreds[gal_index]))

        # Print these properties
        print('+%20s+%20s+%15s+' % ((20 * '-'), (20 * '-'), (15 * '-')))
        print('|%20s|%20s|%15s|' % ('Property'.center(20), 'Value'.center(20),
                                    'Name in code'.center(15)))
        print('+%20s+%20s+%15s+' % ((20 * '-'), (20 * '-'), (15 * '-')))
        print('|%20s|%20s|%15s|' % ('Redshift'.center(20), '{:.3f}'.format(
            self.zreds[gal_index]), 'zred'.center(15)))
        print('|%20s|%20s|%15s|' % ('Radius'.center(20), '{:.3f}'.format(
            np.max(self.R_gal[gal_index])), 'R_gal'.center(15)))
        print('|%20s|%20s|%15s|' % ('Stellar mass'.center(20), '{:.3e}'.format(
            self.M_star[gal_index]), 'M_star'.center(15)))
        print('|%20s|%20s|%15s|' % ('ISM mass'.center(20), '{:.3e}'.format(
            self.M_gas[gal_index]), 'M_gas'.center(15)))
        print('|%20s|%20s|%15s|' %
              ('Dense gas mass fraction'.center(20), '{:.3e}'.format(
                  self.f_dense[gal_index] * 100.), 'f_dense'.center(15)))
        print('|%20s|%20s|%15s|' % ('DM mass'.center(20), '{:.3e}'.format(
            self.M_dm[gal_index]), 'M_dm'.center(15)))
        print('|%20s|%20s|%15s|' % ('SFR'.center(20), '{:.3f}'.format(
            self.SFR[gal_index]), 'SFR'.center(15)))
        print('|%20s|%20s|%15s|' %
              ('SFR surface density'.center(20), '{:.4f}'.format(
                  self.SFRsd[gal_index]), 'SFRsd'.center(15)))
        print('|%20s|%20s|%15s|' %
              ('SFR-weighted Z'.center(20), '{:.4f}'.format(
                  self.Zsfr[gal_index]), 'Zsfr'.center(15)))
        print('+%20s+%20s+%15s+' % ((20 * '-'), (20 * '-'), (15 * '-')))
Beispiel #7
0
    def get_map(self, **kwargs):
        ''' Creates map of surface densities (or sum) of some parameters in sim or ISM data.

        Parameters
        ----------

        quan : str
            What gets mapped, default: 'm'

        ISM_phase : str
            If set, ISM data will be used, default: ''

        sim_type : str
            If set, sim data will be used, default: ''

        get_sum : bool
            If True, return map of summed values not divided by area, default: False
        '''

        # handle default values and kwargs
        args = dict(quan='m',
                    ISM_phase='',
                    sim_type='',
                    grid_length=100,
                    x_res=0.5,
                    get_sum=False)
        args = aux.update_dictionary(args, kwargs)
        for key in args:
            exec(key + '=args[key]')

        # pick data to load
        if ISM_phase != '':
            data = self.get_raw_data(data='ISM')[ISM_phase]
        if sim_type != '':
            data = self.get_raw_data(data='sim')[sim_type]

        # get positional grid
        X = np.arange(-x_max_pc / 1000., x_max_pc / 1000., x_res)  # kpc
        dx = X[-1] - X[-2]
        grid = np.matmul(X[:, None], X[None, :])

        # create empty map
        map_array = np.zeros_like(grid)

        for j, y in enumerate(X[:-1]):
            for k, x in enumerate(X[:-1]):

                # create mask that selects particles in a pixel at position [x,y]
                gas1 = data[(data.y >= X[j]) & (data.y < X[j + 1]) &
                            (data.x >= X[k]) & (data.x < X[k + 1])]

                # get total mass of pixel
                if get_sum: map_array[j, k] = np.sum(gas1[quan].values)
                if not get_sum:
                    map_array[j, k] = np.sum(gas1[quan].values) / dx**2.

        # collect results
        results = dict(X=X, Y=X, Z=map_array, title='', plot_style='map')
        results = aux.update_dictionary(results, kwargs)

        # return plot_it instance
        return results
Beispiel #8
0
def regions(GR, **kwargs):
    '''Creates regions and extracts info from them.

    Parameters
    ----------
    size_arcsec : float
        Size (diameter) of region in arcsec, default: 16.8 arcsec (Croxall+17 Herschel)

    max_regions_per_gal : int
        Max number of regions accepted per galaxy, default: 1000

    line1 : str
        Line ID in line1/line2 ratio, default: 'CII'

    line2 : str
        Line ID in line1/line2 ratio, default: 'NII_205'

    '''
    print('\n--- Creating regions! ---')

    # handle default values and kwargs
    args = dict(size_arcsec=16.6,
                max_regions_per_gal=1000,
                search_within=0.25,
                ISM_phase='GMC',
                line1='CII',
                line2='NII_205',
                extract_from='regions',
                units='Wm2')
    args = aux.update_dictionary(args, kwargs)
    for key in args:
        exec(key + '=args[key]')

    print('Check if a regions file exist...')
    create_regions = False
    if os.path.isfile(d_t + 'model_line_ratios_' + line1 + '_' + line2):
        if ow:
            print(
                'Regions file does exist, but overwrite [ow] is on, will create one! '
            )
            create_regions = True
        if not ow:
            print(
                'Regions file does exist and overwrite [ow] is off, will do nothing. '
            )
    if not os.path.isfile(d_t + 'model_line_ratios_' + line1 + '_' + line2):
        print('Regions file does NOT exist, will create one! ')
        create_regions = True

    if create_regions:
        model_line1 = np.array([])
        model_line2 = np.array([])
        model_SFRsds_exact = np.array([])
        model_SFRsds_CII = np.array([])
        f_CII_neus = np.array([])
        f_neus = np.array([])
        model_F_CII_ergs = np.array([])
        model_Zs_exact = np.array([])
        model_Zs_OH = np.array([])
        gal_indices = np.array([])
        for gal_index in range(0, GR.N_gal):
            print('\nNow doing galaxy number %s' % (gal_index + 1))
            # Initiate galaxy object
            gal_ob = gal.galaxy(gal_index=gal_index)
            # Add region(s) as attribute
            gal_ob.add_attr('regions', **args)
            # Evaluate properties and emission from these regions:
            results = gal_ob.regions.evaluate_regions(gal_ob,
                                                      evaluation_list=[
                                                          'Z', 'SFRsd',
                                                          'line_lum',
                                                          'f_CII_neu', 'f_neu'
                                                      ],
                                                      lines=[line1, line2])
            SFRsds_exact = results['SFRsd']['exact']
            SFRsds_CII = results['SFRsd']['CII']
            F_CII_ergs = results['SFRsd']['F_CII_ergs']  # ergs/s/kpc^2
            F_line1 = aux.Jykm_s_to_W_m2(
                line1, gal_ob.zred,
                results[line1]) / gal_ob.regions.size_sr  # W/m/sr
            F_line2 = aux.Jykm_s_to_W_m2(
                line2, gal_ob.zred,
                results[line2]) / gal_ob.regions.size_sr  # W/m/sr
            f_CII_neu = results['f_CII_neu']
            f_neu = results['f_neu']
            Zs_exact = results['Z']['exact']
            Zs_OH = results['Z']['OH']
            # Convert to line flux in W/m^2
            region_indices = np.arange(len(F_line1))
            # remove regions with no SFRsd or very low line lum:
            mask = (SFRsds_exact > 0) & (F_line1 > Herschel_limits[line1])
            F_line1 = F_line1[mask]
            F_line2 = F_line2[mask]
            SFRsds_exact = SFRsds_exact[mask]
            SFRsds_CII = SFRsds_CII[mask]
            F_CII_ergs = F_CII_ergs[mask]
            f_CII_neu = f_CII_neu[mask]
            f_neu = f_neu[mask]
            region_indices = region_indices[mask]
            Zs_exact = Zs_exact[mask]
            Zs_OH = Zs_OH[mask]
            # Collect results for this galaxy
            model_line1 = np.append(model_line1, F_line1)
            model_line2 = np.append(model_line2, F_line2)
            model_SFRsds_exact = np.append(model_SFRsds_exact, SFRsds_exact)
            model_SFRsds_CII = np.append(model_SFRsds_CII, SFRsds_CII)
            f_CII_neus = np.append(f_CII_neus, f_CII_neu)
            f_neus = np.append(f_neus, f_neu)
            model_F_CII_ergs = np.append(model_F_CII_ergs, F_CII_ergs)
            model_Zs_exact = np.append(model_Zs_exact, Zs_exact)
            model_Zs_OH = np.append(model_Zs_OH, Zs_OH)
            gal_indices = np.append(gal_indices,
                                    np.zeros(len(F_line1)) + gal_index)
            print('Made %s region(s) in %s ' %
                  (len(F_line1), GR.galnames[gal_index]))
            print('SFR of this galaxy: %s' % gal_ob.SFR)
            print('SFR-weighted Z of this galaxy: %s' % gal_ob.Zsfr)
            print(
                'Median of mass-weighted mean metallicities extracted for this galaxy: %s'
                % (np.median(Zs_exact.values)))
            # Visualize region(s)
            gal_ob.regions.plot_positions(gal_ob,
                                          region_indices,
                                          line='CII',
                                          convolve=True,
                                          units='Wm2_sr')
        # Save result:
        results             =   pd.DataFrame(dict(SFRsd_exact=model_SFRsds_exact,SFRsd_CII=model_SFRsds_CII,\
                                f_CII_neu=f_CII_neus,f_neu=f_neus,line1=model_line1,line2=model_line2,F_CII_ergs=model_F_CII_ergs,\
                                Z_exact=model_Zs_exact,Z_OH=model_Zs_OH,gal_indices=gal_indices))
        results['line_ratio'] = results['line1'] / results['line2']
        results.to_pickle(d_t + 'model_line_ratios_' + line1 + '_' + line2)
        print('Done! In total: %s region(s) with detectable flux\n' %
              (len(results)))