Exemple #1
0
def calcM2L(filter, age, Z, imf, best_spec=None, z=0.0, bandcor=False, plot=False, change_units=True):

    """
    Given a spectrum with an age, Z and IMF, calculate its M/L ratio in a given filter.
    Assume we just want the visible here- if not, make sure you change the range of your
    templates to include the filter bandpass!
    """
    factor= (L_sun/1e4/(10.0*ST.pc*100.0)**2.0) / (4.0*np.pi)
    
    
    if best_spec is None:
        lam_range_temp=[3000, 11000]       
        from stellarpops.tools import fspTools as FT
        interp, lin_lams= FT.prepare_linear_CvD_interpolator(lam_range_temp, verbose=False)
        best_spec=ST.spectrum(lin_lams, interp((lin_lams, age, Z, imf))*factor)
    else:
        if change_units:
            best_spec=ST.spectrum(best_spec.lam, best_spec.flam*factor)
    m=get_mass_for_spec(age, Z, imf)

    sol = ST.loadHSTSolarSpec()
    lsun = sol.calcABmag(filter, z=z, bandcor=bandcor, plot=False)
    msun = 1.0

    l = best_spec.calcABmag(filter, z=z, bandcor=bandcor, plot=False)

    m2l = (m/10.0**(-0.4*l)) / (msun/10.0**(-0.4*lsun))

    return m2l
Exemple #2
0
def load_measure_NGC1277_LRIS_indices(filename, indices):

    import os
    filename = os.path.expanduser(filename)

    lam, flux, error, _, _ = np.genfromtxt(filename, unpack=True)

    lamdas = lam / 1.017044
    spectrum = ST.spectrum(lam=lamdas,
                           lamspec=flux,
                           wavesyst='vac',
                           errlamspec=error)

    data = np.empty(len(indices))
    errors = np.empty(len(indices))

    for i, index in enumerate(indices):
        indval = ST.clip_spec_measure_index(spectrum, index)

        data[i] = indval[0]
        errors[i] = indval[1]

    #Make the TiO index have a small error. FIXME!
    errors[-2] = 0.005

    # #indices- NaI, FeH, MgI, TiO89  ### Hbeta, Mgb, Fe52, Fe53
    # data=np.array([1.03586, 0.37062, 0.54611, 1.07290])#, 1.222, 4.704, 2.799, 2.122])

    return data, errors
Exemple #3
0
def load_base_CvD16ssps(dirname='/Data/stellarpops/CvD2/', folder='vcj_models', verbose=True):

    import os
    dirname=os.path.expanduser(dirname)

    vcj_models=sorted(glob.glob('{}/{}/VCJ_*.s100'.format(dirname, folder)))
    temp_lamdas, x35, x3, x23, kroupa, flat=np.genfromtxt(vcj_models[0], unpack=True)


    model_Zs_names=['m1.5', 'm1.0', 'm0.5', 'p0.0', 'p0.2']
    Zs=[-1.5, -1.0, -0.5, 0.0, 0.2]
    ages=[1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.5]
    model_imfs_order=['x35', 'x3', 'x23', 'kroupa', 'flat']

    n_ages=len(ages)
    n_zs=len(Zs)
    n_imfs=len(model_imfs_order)

    
    spectra={}
    

    templates=np.empty( (n_imfs, n_ages, n_zs, len(x35)) )

    for a, Z in enumerate(model_Zs_names):

        for b, age in enumerate(ages):

            model=glob.glob('{}/{}/VCJ_*{}*{}.ssp.s100'.format(dirname, folder, Z, age))[0]
            if verbose:
                print 'Loading {}'.format(model)
            data=np.genfromtxt(model)

            for i, imf in enumerate(model_imfs_order):
                templates[i, b, a, :]=data[:, i+1]

    age_values=np.repeat(ages, len(Zs)).reshape(len(ages), len(Zs))
    Z_values=np.repeat(Zs, len(ages)).reshape(len(Zs), len(ages)).T


    
       
    for i, imf in enumerate(model_imfs_order):

        spectra[imf]=ST.spectrum(lam=temp_lamdas, lamspec=templates[i, :, :, :], age=age_values, IMF=imf, Z=Z_values, wavesyst='vac')

    return spectra
Exemple #4
0
def load_measure_NGC1277_WHT_indices(filename, indices):

    import os
    filename = os.path.expanduser(filename)

    lam, flux, err = np.genfromtxt(filename, unpack=True)

    WHT_spectrum = ST.spectrum(lam=lam,
                               lamspec=flux,
                               wavesyst='air',
                               errlamspec=err)

    data = np.empty(len(indices))
    errors = np.empty(len(indices))

    for i, index in enumerate(indices):
        indval = ST.clip_spec_measure_index(WHT_spectrum, index)

        data[i] = indval[0]
        errors[i] = indval[1]

    return data, errors
Exemple #5
0
def get_element_enhanced_spec(spec, element, enhancement=0.3, base_enhancement=0.3, varelem_dict=None, elem_param_dict=None, base_param_dict=None):

    """Take a CvD variable element spectrum and find its ratio with the solar abundance pattern spectrum. Apply this ratio as a response function to another spectrum.
    Enhancement should always be positive
    """

    if varelem_dict is None:
        if spec.IMF in ['flat', 'kroupa']:
            varelem_dict=load_varelem_CvD16ssps(imf='kroupa')
        elif spec.IMF in ['x35', 'x3', 'x23']:
            varelem_dict=load_varelem_CvD16ssps(imf='salp')
        else:
            raise NameError('IMF type not understood- check spectrum.IMF exists or load the varelem dictionary separately.')
    if elem_param_dict is None:
        elem_param_dict=CD16_get_np_indices_for_elems()
    if base_param_dict is None:
        base_param_dict=CD16_get_np_indices_for_params()


    assert enhancement>=0.0, 'Enhancement should always be positive. To make an under-enhanced spectrum, use Elem- with enhancement >0, e.g. Na-, +0.3'


    assert element in varelem_dict.keys(), 'Pick an element which is in the CvD variable element file'



    factor = (varelem_dict[element].flam/varelem_dict['Solar'].flam-1)*((10**(enhancement)-1.0)/(10**(base_enhancement)-1.0))


    #Bit of a hack: we want to select the ages from the original array which are also in the varying elemental abundance spectra: 1, 3, 5, 9, 13 but ignoring 7 and 11 Gyrs.    
    if spec.flam.shape !=factor.shape:
        age_axis_mask=np.array([True, True, True, False, True, False, True])
    else:
        age_axis_mask=np.ones(spec.flam.shape[0]).astype(bool)

    newspec=ST.spectrum(lam=spec.lam, lamspec=np.exp(np.log(spec.flam[age_axis_mask, :, :])+factor), age=spec.age[age_axis_mask, :], Z=spec.Z[age_axis_mask, :], IMF=spec.IMF, wavesyst='vac', userdict={'elem':element})

    return newspec 
Exemple #6
0
def load_varelem_CvD16ssps(dirname='/Data/stellarpops/CvD2', folder='atlas_rfn_v3', imf='kroupa', verbose=True):


    import os
    dirname=os.path.expanduser(dirname)

    if imf in ['kroupa', 'krpa', 'Kroupa', 'Krpa']:
        model_spectra=sorted(glob.glob('{}/{}/atlas_ssp_*.krpa.s100'.format(dirname, folder)))
        imf_name='krpa'
    elif imf in ['Salpeter', 'salpeter', 'salp', 'Salp']:
        model_spectra=sorted(glob.glob('{}/{}/atlas_ssp_*.salp.s100'.format(dirname, folder)))
        imf_name='salp'
    else:
        raise NameError('IMF type not understood')
    
    
    data=np.genfromtxt(model_spectra[0])
    lams=data[:, 0]

    model_Zs_names=['m1.5', 'm1.0', 'm0.5', 'p0.0', 'p0.2']
    model_age_names=['01', '03', '05', '09', '13']

    model_elem_order=['Solar', 'Na+', 'Na-', 'Ca+', 'Ca-', 'Fe+', 'Fe-', 'C+', 'C-', 'a/Fe+', 'N+', 'N-', 'as/Fe+', 'Ti+', 'Ti-', 
    'Mg+', 'Mg-', 'Si+', 'Si-', 'T+', 'T-', 'Cr+', 'Mn+', 'Ba+', 'Ba-', 'Ni+', 'Co+', 'Eu+', 'Sr+', 'K+','V+', 'Cu+', 'Na+0.6', 'Na+0.9']


    Zs=[-1.5, -1.0, -0.5, 0.0, 0.2]
    ages=[float(a) for a in model_age_names]

    n_ages=len(model_age_names)
    n_zs=len(model_Zs_names)
    n_elems=len(model_elem_order)

    templates=np.empty( (n_elems, n_ages, n_zs, len(lams)) )

    for a, Z in enumerate(model_Zs_names):
        for b, age in enumerate(model_age_names):


            
            model=glob.glob('{}/{}/atlas_ssp*t{}*{}*{}.s100'.format(dirname, folder, age, Z, imf_name))[0]
            if verbose:
                print 'Loading {}'.format(model)
            data=np.genfromtxt(model)



            for i, elem in enumerate(model_elem_order):
                templates[i, b, a, :]=data[:, i+1]


    
    spectra={}
    for i, elem in enumerate(model_elem_order):

        
        age_values=np.repeat(ages, n_zs).reshape(n_ages, n_zs)
        Z_values=np.repeat(Zs, n_ages).reshape(n_zs, n_ages).T

        spectra[elem]=ST.spectrum(lam=lams, lamspec=templates[i, :, :, :], age=age_values, Z=Z_values, wavesyst='vac', userdict={'elem':elem})

    return spectra
Exemple #7
0
def loadCD12ssps(sedpath=cd12tools_basedir+"CvD12_v1.2", ageglob="t??.?_solar.ssp", massfile="mass_ssp.dat", model="CD12", Z=0.02, verbose=True):
    """
    Author:  Ryan Houghton (18/09/12)

    Purpose: Load one of the Conroy / van Dokkum Z=SOLAR, varying age, SSP models, keeping:
       - IMF (string)
       - Age (Gyr)
       - Metallicity Z
       - Wavelength (AA)
       - Flux density (erg/s/AA/cm^2)
    
    """
    # get the AGE files to read in
    afiles, nafiles = ST.findfiles(expanduser(sedpath)+"/"+ageglob)

    # get mass info
    minfo = at.Table(expanduser(sedpath)+"/"+massfile, type="ascii")
    imftags = minfo.col1
    masses = np.array([minfo.col2, minfo.col3, minfo.col4, minfo.col5, minfo.col6, minfo.col7])

    # convert: L_sun/micron => * L_sun[erg/s] / 1e4 / (4.*pi*D[cm]**2) => erg/s/cm**2/AA (@10pc)
    factor= (L_sun/1e4/(10.0*ST.pc*100.0)**2.0) / (4.0*np.pi)

    # read SSP files one by one
    ages=[]
    Zs=[]
    imfs=[]
    flux1=[]
    flux2=[]
    flux3=[]
    flux4=[]
    flux5=[]
    wave=None
    for f in afiles:
        # load table
        ssp  = at.Table(f, type='ascii')
        # get age of file
        ages.append(float(f[-14:-10]))
        # get metallicity
        Zs.append(Z)
        # get imfs of fluxes
        imfs.append(imftags) 
        # get wave (once)
        if wave==None: wave = ssp.col1
        # get fluxes for each IMF
        flux1.append(ssp.col2*factor)
        flux2.append(ssp.col3*factor)
        flux3.append(ssp.col4*factor)
        flux4.append(ssp.col5*factor)
        flux5.append(ssp.col6*factor)
        if verbose: print("Loaded "+f)


    flux=[]
    flux.append(np.array(flux1))
    flux.append(np.array(flux2))
    flux.append(np.array(flux3))
    flux.append(np.array(flux4))
    flux.append(np.array(flux5))
    # now make spectra for age variations, one for each IMF
    specs=[]
    for q in range(5):
        spec = ST.spectrum(lamspec=flux[q], lam=wave, age=ages, mass=masses[:,q], \
                          Z=Zs[q], IMF=imftags[q], model=model, wavesyst="vac")
        specs.append(spec)

    return specs
Exemple #8
0
def loadCD12spec(filepath):
    """
    Originally written by Simon Zieleniewski.
    Adapted by Ryan Houghton. 

    Function to read in CvD12 SSP files and return spectra as a
        spectrum class (created by RCWH).

    Inputs:
    =======
    - filepath: Path and filename string of file for CvD spectra

    Outputs:
    ========
    - spectrum: A spectrum class for the given SSP SED.
                Initialised with units (lambda=A, flux=erg/s/cm2/A) @ D=10pc


    e.g
    
    csalpha= loadCD12spec(basedir+"CvD12_v1.2/t13.5_varelem.ssp")
    csabun = loadCD12spec(basedir+"CvD12_v1.2/t13.5_varelem.ssp")

    """  

    dat = np.genfromtxt(filepath)

    #Get filename
    fname = filepath.split('/')[-1]

    #Wavelenghts in A
    lambs = dat[:,0].copy()

    #Set flux units to erg/s/cm**2/A at D = 10 pc. CvD flux in units of L_sun/um
    flux = np.transpose(dat[:,1:].copy())
    factor = (L_sun/1e4/(10.0*ST.pc*100.0)**2.0) / (4.0*np.pi)
    flux *= factor

    #Age of spectra in Gyrs
    Age = [float(fname.split('_')[0].split('t')[1])]*flux.shape[0]
    

    #Interpolate to get linear dispersion
    newlambs = np.linspace(lambs[0], lambs[-1], len(lambs))
    finterp = interpolate.interp1d(lambs, flux, kind='linear', axis=-1)
    newflux = finterp(newlambs)

    #Get mass file
    masspath = filepath.split(fname)[0]
    masses_orig = np.loadtxt(masspath+'mass_ssp.dat', dtype=np.str)
    masses = np.copy(masses_orig)
    masspos = {13.5:6, 11.0:5, 9.0:4, 7.0:3, 5.0:2, 3.0:1}
    mass = np.array(masses[:,masspos[Age[0]]], dtype=np.float)

    #Depending on filename, spectra correspond to different IMFs, ages etc
    if 'solar' in fname:
        #IMFs = x=3.5, 3.0, 2.35, Chabrier, bottom-light
        IMFs = ['x = 3.5', 'x = 3.0', 'x = 2.35', 'Chabrier', 'bottom-light']
        return ST.spectrum(lamspec=newflux, lam=newlambs, age=Age,
                          Z=0.2, IMF=IMFs, model='CD12', mass=mass, wavesyst="vac")

    if 'afe' in fname:
        met = 0.0
        IMFs = ['x = 3.5', 'x = 3.0', 'x = 2.35', 'Chabrier', 'bottom-light']
        afes = {'afe': float(fname.split('+')[1][0:3])}
        return ST.spectrum(lamspec=newflux, lam=newlambs, age=Age, alpha=afes['afe'], 
                          Z=met, IMF=IMFs, model='CD12', 
                          mass=mass, wavesyst="vac") #userdict=afes,

    if 'varelem' in fname:
        IMF = 'Chabrier'
        uAge = list(set(Age))[0]
        met = 0.0
        massloc = np.where(masses[:,0]==IMF)[0]
        masses = masses[massloc[0],1:]
        mass = float(masses[masspos[uAge]-1])
        
        abunlist = {'abundances': ['[Na/Fe] = +0.3', '[Na/Fe] = -0.3','[Ca/Fe] = +0.15', '[Ca/Fe] = -0.15',
                '[Fe/H] = +0.3', '[Fe/H] = -0.3', '[C/Fe] = +0.15', '[C/Fe] = -0.15',
                '[a/Fe] = +0.2', '[as/Fe] = +0.2', '[N/Fe] = +0.3', '[N/Fe] = -0.3',
                '[Ti/Fe] = +0.3', '[Ti/Fe] = -0.3', '[Mg/Fe] = +0.3', '[Mg/Fe] = -0.3',
                '[Si/Fe] = +0.3', '[Si/Fe] = -0.3']}
        return ST.spectrum(lamspec=newflux, lam=newlambs, age=Age,
                          Z=met, IMF=IMF, model='CD12', userdict=abunlist,
                          mass=mass, wavesyst="vac")

    else:
        raise ValueError('Did not input correct CD12 file [as of 03-04-14]')