示例#1
0
def random_gal(galreal,Nrand,Nmin=10):
    """ Prefered random galaxy generator. For a given galaxy with a
    given magnitude (and other properties), it calculates the redshift
    sensitivity function from galaxies in a magnitude band around the
    selected one (i.e., including slightly brighter and fainter
    galaxies), and places Nrand new galaxies at a random redshift given
    by a smoothed version of the observed sensitivity function. For
    extremely bright or faint galaxies (rare) the sensitivity function
    is calculated from at least Nmin (=50) galaxies (i.e. the magnitude
    band is increased)."""
    
    from astro.sampledist import RanDist
    from astro.fit import InterpCubicSpline
    from scipy.ndimage import gaussian_filter as gf
    
    Ckms  = 299792.458
    Nmin  = int(Nmin)  #minimum number of galaxys for the fit
    zmin  = np.min(galreal.ZGAL)
    zmax  = np.max(galreal.ZGAL) + 0.1
    DZ    = 0.01       #delta z for the histogram for getting the spline in z
    smooth_scale = 10. #smoothing scale for the histogram (in number
                       #of bins, so depends on DZ)
    galreal.sort(order='MAG') #np.recarray.sort()
    galrand = galreal.repeat(Nrand)
    delta_mag = 0.5 # half of the magnitude bandwidth to generate the z histogram
    
    bins = np.append(np.linspace(0,zmin,20),np.arange(zmin+DZ, zmax, DZ))
    
    for i in xrange(len(galreal)):
        if i < Nmin: 
            vals,bins = np.histogram(galreal.ZGAL[:Nmin], bins)
            vals      = gf(vals.astype(float),smooth_scale) # smooth the histogram
            spl       = InterpCubicSpline(0.5*(bins[:-1] + bins[1:]), vals.astype(float))
            
        else:
            delta_mag2=delta_mag
            while True:
                cond = (galreal.MAG > 0) & (galreal.MAG < 90) 
                cond = cond & (galreal.MAG<=galreal.MAG[i]+delta_mag2)&(galreal.MAG>galreal.MAG[i]-delta_mag2)
                if np.sum(cond)>=Nmin:
                    break
                else:
                    delta_mag2+=0.1
            vals,bins = np.histogram(galreal.ZGAL[cond], bins)
            vals      = gf(vals.astype(float),smooth_scale) # smooth the histogram
            spl       = InterpCubicSpline(0.5*(bins[:-1] + bins[1:]), vals.astype(float))
        
        rvals     = np.linspace(0, zmax, 1e4)
        rand_z    = RanDist(rvals, spl(rvals))
        zrand     = rand_z.random(Nrand)
        
        integer_random2 = np.random.randint(0,len(galreal),Nrand) #for RA,DEC  
        RArand  = galreal.RA[integer_random2]
        DECrand = galreal.DEC[integer_random2]
        galrand.ZGAL[i*Nrand:(i+1)*Nrand] = zrand
        galrand.RA[i*Nrand:(i+1)*Nrand]   = RArand
        galrand.DEC[i*Nrand:(i+1)*Nrand]  = DECrand
    return galrand
示例#2
0
def random_gal(galreal,Nrand,Nmin=20):
    """ Prefered random galaxy generator. For a given galaxy with a
    given magnitude (and other properties), it calculates the redshift
    sensitivity function from galaxies in a magnitude band around the
    selected one (i.e., including slightly brighter and fainter
    galaxies), and places Nrand new galaxies at a random redshift given
    by a smoothed version of the observed sensitivity function. For
    extremely bright or faint galaxies (rare) the sensitivity function
    is calculated from at least Nmin (=50) galaxies (i.e. the magnitude
    band is increased)."""
    
    from astro.sampledist import RanDist
    from astro.fit import InterpCubicSpline
    from scipy.ndimage import gaussian_filter as gf
    
    Ckms  = 299792.458
    Nmin  = int(Nmin)  #minimum number of galaxys for the fit
    zmin  = np.min(galreal.ZGAL)
    zmax  = np.max(galreal.ZGAL) + 0.1
    DZ    = 0.01     #delta z for the histogram for getting the spline in z
    smooth_scale = 10. #smoothing scale for the histogram (in number
                       #of bins, so depends on DZ)
    galreal.sort(order='MAG') #np.recarray.sort()
    galrand = galreal.repeat(Nrand)
    delta_mag = 0.5 # half of the magnitude bandwidth to generate the z histogram
    
    bins = np.append(np.linspace(0,zmin,20),np.arange(zmin+DZ, zmax, DZ))
    
    for i in xrange(len(galreal)):
        if i < Nmin: 
            vals,bins = np.histogram(galreal.ZGAL[:Nmin], bins)
            vals      = gf(vals.astype(float),smooth_scale) # smooth the histogram
            spl       = InterpCubicSpline(0.5*(bins[:-1] + bins[1:]), vals.astype(float))
            
        else:
            delta_mag2=delta_mag
            while True:
                cond = (galreal.MAG > 0) & (galreal.MAG < 90) 
                cond = cond & (galreal.MAG<=galreal.MAG[i]+delta_mag2)&(galreal.MAG>galreal.MAG[i]-delta_mag2)
                if np.sum(cond)>=Nmin:
                    break
                else:
                    delta_mag2+=0.1
            vals,bins = np.histogram(galreal.ZGAL[cond], bins)
            vals      = gf(vals.astype(float),smooth_scale) # smooth the histogram
            spl       = InterpCubicSpline(0.5*(bins[:-1] + bins[1:]), vals.astype(float))
        
        rvals     = np.linspace(0, zmax, 1e4)
        rand_z    = RanDist(rvals, spl(rvals))
        zrand     = rand_z.random(Nrand)
        galrand.ZGAL[i*Nrand:(i+1)*Nrand] = zrand
    return galrand
示例#3
0
def random_abs(absreal, Nrand, wa, er, sl=3, R=20000, ion='HI'):
    """From a real absorber catalog it creates a random catalog.  For
    a given real absorber with (z_obs,logN_obs,b_obs) it places it at
    a new z_rand, defined by where the line could have been
    observed. 
    
    Input parameters:
    ---
    absreal: numpy rec array with the absorber catalog.
    Nrand:   number of random lines per real one generated (integer).
    wa:      numpy array of wavelenght covered by the spectrum.  
    er:      numpy array of error in the normalized flux of the spectrum for 
             a given wavelenght.
    sl:      significance level for the detection of the absorption line.
    
    From the error we calculate the Wmin = sl * wa * er / (1+z) / R,
    where z = wa/w0 - 1 (w0 is the rest frame wavelenght of the
    transition) and R is the resolution of the spectrograp. We then
    smooth Wmin with a boxcar (sharp edges). 
    
    For the given absorber we transform (logN_obs,b_obs) to a W_obs assuming 
    linear part of the curve-of-growth. 
    
    We then compute the redshifts where W_obs could have been observed
    according to the given Wmin, and place Nrand new absorbers with
    the same properties as the given one accordingly.
    """
    from astro.sampledist import RanDist
    from scipy.ndimage import gaussian_filter as gf

    absreal.sort(order='LOGN')  #np.recarray.sort() sorted by column density
    Nrand = int(Nrand)
    absrand = absreal.repeat(Nrand)
    Ckms = 299792.458
    if ion == 'HI':
        w0 = 1215.67  # HI w0 in angstroms
    z = wa / w0 - 1.  # spectrum in z coordinates

    er = np.where(er == 0, 1e10, er)
    er = np.where(np.isnan(er), 1e10, er)
    Wmin = 3 * sl * w0 * er / R  #3*sl*wa*er / (1. + z) / R
    Wmin = gf(Wmin.astype(float), 10)  # smoothed version

    for i in xrange(len(absreal)):
        Wr = logN_b_to_Wr(absreal.LOGN[i], absreal.B[i], ion='HI')
        zgood = (Wr > Wmin) & (z > 0)
        rand_z = RanDist(z, zgood * 1.)
        zrand = rand_z.random(Nrand)
        absrand.ZABS[i * Nrand:(i + 1) * Nrand] = zrand

    return absrand
示例#4
0
def random_abs(absreal,Nrand,wa,er,sl=3,R=20000,ion='HI'):
    """From a real absorber catalog it creates a random catalog.  For
    a given real absorber with (z_obs,logN_obs,b_obs) it places it at
    a new z_rand, defined by where the line could have been
    observed. 
    
    Input parameters:
    ---
    absreal: numpy rec array with the absorber catalog.
    Nrand:   number of random lines per real one generated (integer).
    wa:      numpy array of wavelenght covered by the spectrum.  
    er:      numpy array of error in the normalized flux of the spectrum for 
             a given wavelenght.
    sl:      significance level for the detection of the absorption line.
    
    From the error we calculate the Wmin = sl * wa * er / (1+z) / R,
    where z = wa/w0 - 1 (w0 is the rest frame wavelenght of the
    transition) and R is the resolution of the spectrograp. We then
    smooth Wmin with a boxcar (sharp edges). 
    
    For the given absorber we transform (logN_obs,b_obs) to a W_obs assuming 
    linear part of the curve-of-growth. 
    
    We then compute the redshifts where W_obs could have been observed
    according to the given Wmin, and place Nrand new absorbers with
    the same properties as the given one accordingly.
    """
    from astro.sampledist import RanDist
    from scipy.ndimage import gaussian_filter as gf
    
    absreal.sort(order='LOGN') #np.recarray.sort() sorted by column density
    Nrand   = int(Nrand)
    absrand = absreal.repeat(Nrand)
    Ckms  = 299792.458
    if ion=='HI':
        w0    = 1215.67  # HI w0 in angstroms
    z     = wa/w0 - 1.   # spectrum in z coordinates
    
    er   = np.where(er==0,1e10,er)
    er   = np.where(np.isnan(er),1e10,er)
    Wmin = 3*sl*w0*er/R  #3*sl*wa*er / (1. + z) / R
    Wmin = gf(Wmin.astype(float),10) # smoothed version 
    
    for i in xrange(len(absreal)):
        Wr     = logN_b_to_Wr(absreal.LOGN[i],absreal.B[i],ion='HI')
        zgood  = (Wr > Wmin) & (z>0)
        rand_z = RanDist(z, zgood*1.)
        zrand  = rand_z.random(Nrand)
        absrand.ZABS[i*Nrand:(i+1)*Nrand] = zrand

    return absrand 
示例#5
0
def random_abs(absreal,Nrand,wa,fl,er,sl=3.,R=20000,FWHM=10.,ion='HI'):
    """From a real absorber catalog it creates a random catalog.  For
    a given real absorber with (z_obs,logN_obs,b_obs) it places it at
    a new z_rand, defined by where the line could have been
    observed. 
    
    Input parameters:
    ---
    absreal: numpy rec array with the absorber catalog.
    Nrand:   number of random lines per real one generated (integer).
    wa:      numpy array of wavelenght covered by the spectrum.
    fl:      numpy array of normalized flux.
    er:      numpy array of error in the normalized flux of the spectrum for 
             a given wavelenght.
    sl:      significance level for the detection of the absorption line.
    R:       resolution of the spectrograph, assumed constant
    FWHM:    Full-width at half maximum in pixels (assumed constant). This 
             parameter defines the smoothing scale for Wmin. 
    ion:     Name of the ion. Function only valid for HI so far.
    
    From the error we calculate the Wmin = sl * wa * er / (1+z) / R,
    where z = wa/w0 - 1 (w0 is the rest frame wavelenght of the
    transition) and R is the resolution of the spectrograp. We then
    smooth Wmin with a boxcar along FWHM pixels. 
    
    For the given absorber we transform (logN_obs,b_obs) to a W_obs assuming 
    linear part of the curve-of-growth. 
    
    We then compute the redshifts where W_obs could have been observed
    according to the given Wmin, and place Nrand new absorbers with
    the same properties as the given one accordingly.
    """
    from astro.sampledist import RanDist
        
    absreal.sort(order='LOGN') #np.recarray.sort() sorted by column density
    Nrand   = int(Nrand)
    absrand = absreal.repeat(Nrand)
    Ckms  = 299792.458
    if ion=='HI':
        z_Lya, Wmin_Lya = compute_Wmin(wa,fl,er,sl=sl,R=R,FWHM=FWHM,ion='HI')
        z_Lyb, Wmin_Lyb = compute_Wmin(wa,fl,er,sl=sl,R=R,FWHM=FWHM,ion='HILyb')
        
    for i in xrange(len(absreal)):
        if absreal.ZABS[i]>np.max(z_Lya): # lines that were observed through Lyb
            Wr   = logN_b_to_Wr(absreal.LOGN[i],absreal.B[i],ion='HILyb')
            z    = z_Lyb
            z    = np.where(z<=z_Lya,-1.,z) #mask out region with Lya coverage
            Wmin = Wmin_Lyb
        else: #lines that were observed through Lya only
            Wr   = logN_b_to_Wr(absreal.LOGN[i],absreal.B[i],ion='HI')
            z    = z_Lya
            Wmin = Wmin_Lya

        zgood  = (Wr > Wmin) & (z>0)
        assert np.sum(zgood)>0, \
            'There are not regions in the spectrum with Wmin<%s A. Addjust significance.' %(Wr)
        
        rand_z = RanDist(z, zgood*1.)
        zrand  = rand_z.random(Nrand)
        absrand.ZABS[i*Nrand:(i+1)*Nrand] = zrand

    return absrand 
示例#6
0
def random_abs(zobs,
               Wobs,
               Nrand,
               wa,
               fl,
               er,
               sl=3.,
               R=20000,
               FWHM=10.,
               wa0=1215.67,
               zmax=None,
               zmin=None):
    """From a list of observed redshifts (zobs) and observed rest-frame
    equivalent widths (Wobs), it creates a random catalog.  For a given
    real absorber with Wobs it creates Nrand random ones at the new
    zrand, defined by where the line could have been observed. It
    returns those zrand.
    
    Inputs
    ------
    zobs:    observed redshifts.
    Wobs:    observed rest-frame equivalent widths (in A).
    Nrand:   number of randWr = logN_b_to_Wr()om lines per real one generated (integer).
    wa:      numpy array of wavelenght covered by the spectrum.
    fl:      numpy array of normalized flux.
    er:      numpy array of error in the normalized flux of the spectrum for 
             a given wavelenght.
    sl:      significance level for the detection of the absorption line.
    R:       resolution of the spectrograph, assumed constant
    FWHM:    Full-width at half maximum in pixels (assumed constant). This 
             parameter defines the smoothing scale for Wmin. 
    wa0:     rest-frame wavelenght (in A).
    zmax:    if given, is the maximum redshift allowed for the randoms
    zmin:    if given, is the minimum redshift allowed for the randoms
    
    We first compute Wmin (see abslines.Wmin). We compute the redshifts
    where Wobs could have been observed according to the given Wmin,
    and place Nrand new absorbers with the same properties as the given
    one accordingly.
    """
    zobs = np.array(zobs)
    Wobs = np.array(Wobs)
    wa = np.array(wa)
    fl = np.array(fl)
    er = np.array(er)

    assert len(zobs)==len(Wobs), \
        'zobs and Wobs do not have same dimensions!'
    assert (len(wa)==len(fl)) and (len(wa)==len(er)),\
        'wa,fl and er do not have same dimensions!'

    Nrand = int(Nrand)
    zrand = zobs.repeat(Nrand)

    z, Wmin = compute_Wmin(wa, fl, er, sl=sl, R=R, FWHM=FWHM, wa0=wa0)

    if zmax is None:
        zmax = 1000.  ## Here, sort out zlims
    if zmin is None:
        zmin = 0.

    for i in xrange(len(Wobs)):

        zgood = (Wobs[i] > Wmin) & (z >= zmin) & (z < zmax)

        if np.sum(zgood) == 0:  #This is not good so plot situation.
            pl.plot(z, Wmin, drawstyle='steps-mid')
            pl.axis([z[0], z[-1], 0, 0.1])
            pl.show()
            print Wmin
        assert np.sum(zgood)>0, \
            'There are not regions in the spectrum with Wmin<{} A. The minimum is {} A. Adjust significance.'.format(Wobs,np.min(Wmin))

        rand_z = RanDist(z, zgood * 1.)
        aux = rand_z.random(Nrand)
        zrand[i * Nrand:(i + 1) * Nrand] = aux

    return zrand
示例#7
0
def random_abs(zobs,Wobs,Nrand,wa,fl,er,sl=3.,R=20000,FWHM=10.,wa0=1215.67,zmax=None,zmin=None):
    """From a list of observed redshifts (zobs) and observed rest-frame
    equivalent widths (Wobs), it creates a random catalog.  For a given
    real absorber with Wobs it creates Nrand random ones at the new
    zrand, defined by where the line could have been observed. It
    returns those zrand.
    
    Inputs
    ------
    zobs:    observed redshifts.
    Wobs:    observed rest-frame equivalent widths (in A).
    Nrand:   number of randWr = logN_b_to_Wr()om lines per real one generated (integer).
    wa:      numpy array of wavelenght covered by the spectrum.
    fl:      numpy array of normalized flux.
    er:      numpy array of error in the normalized flux of the spectrum for 
             a given wavelenght.
    sl:      significance level for the detection of the absorption line.
    R:       resolution of the spectrograph, assumed constant
    FWHM:    Full-width at half maximum in pixels (assumed constant). This 
             parameter defines the smoothing scale for Wmin. 
    wa0:     rest-frame wavelenght (in A).
    zmax:    if given, is the maximum redshift allowed for the randoms
    zmin:    if given, is the minimum redshift allowed for the randoms
    
    We first compute Wmin (see abslines.Wmin). We compute the redshifts
    where Wobs could have been observed according to the given Wmin,
    and place Nrand new absorbers with the same properties as the given
    one accordingly.
    """
    zobs = np.array(zobs)
    Wobs = np.array(Wobs)
    wa = np.array(wa)
    fl = np.array(fl)
    er = np.array(er)

    assert len(zobs)==len(Wobs), \
        'zobs and Wobs do not have same dimensions!'
    assert (len(wa)==len(fl)) and (len(wa)==len(er)),\
        'wa,fl and er do not have same dimensions!'

    Nrand   = int(Nrand)
    zrand   = zobs.repeat(Nrand)
    
    z, Wmin = compute_Wmin(wa,fl,er,sl=sl,R=R,FWHM=FWHM,wa0=wa0)
    
    if zmax is None:
        zmax = 1000. ## Here, sort out zlims
    if zmin is None:
        zmin = 0.

    for i in xrange(len(Wobs)):
        
        zgood  = (Wobs[i] > Wmin) & (z >= zmin) & ( z < zmax)
        
        if np.sum(zgood)==0: #This is not good so plot situation.
            pl.plot(z,Wmin,drawstyle='steps-mid')
            pl.axis([z[0],z[-1],0,0.1])
            pl.show()
            print Wmin
        assert np.sum(zgood)>0, \
            'There are not regions in the spectrum with Wmin<{} A. The minimum is {} A. Adjust significance.'.format(Wobs,np.min(Wmin))
        
        rand_z = RanDist(z, zgood*1.)
        aux    = rand_z.random(Nrand)
        zrand[i*Nrand:(i+1)*Nrand] = aux

    return zrand