def load_PS1_data(lc_filename):
    # load cleaned PS1 data and correct magnitude errors
    lc_ps = np.genfromtxt(lc_filename, usecols=(1, 2, 3, 6, 8, 17), names='mag_err, ra, dec, filter, mjd_obs, ucalmag', dtype='f8, f8, f8, |S5, f8, f8')
    lc_ps['mag_err'] = np.sqrt((1.3*lc_ps['mag_err'])**2 + 0.015**2)
    # correct PS1 light curves for extinction
    gl, gb = eq2gal(lc_ps['ra'][0], lc_ps['dec'][0])
    EBV = getval(gl, gb)
    for band, c in zip(['g', 'r', 'i', 'z', 'y'], [3.172, 2.271, 1.682, 1.322, 1.087]):
        lc_ps['ucalmag'][lc_ps['filter'] == band] -= c*EBV
    # light curve data used in fitting
    lc_data = [lc_ps['mjd_obs'][lc_ps['filter'] == 'g'], lc_ps['ucalmag'][lc_ps['filter'] == 'g'], lc_ps['mag_err'][lc_ps['filter'] == 'g'], lc_ps['mjd_obs'][lc_ps['filter'] == 'r'], lc_ps['ucalmag'][lc_ps['filter'] == 'r'], lc_ps['mag_err'][lc_ps['filter'] == 'r'], lc_ps['mjd_obs'][lc_ps['filter'] == 'i'], lc_ps['ucalmag'][lc_ps['filter'] == 'i'], lc_ps['mag_err'][lc_ps['filter'] == 'i'], lc_ps['mjd_obs'][lc_ps['filter'] == 'z'], lc_ps['ucalmag'][lc_ps['filter'] == 'z'], lc_ps['mag_err'][lc_ps['filter'] == 'z']]
    return lc_data
Ejemplo n.º 2
0
def extinction_prior(ob):
    import dust
    avfac = 2.742  # SF11, R(V) = 3.1 for Landolt A(V)
    # any star with an extinction prior gets an E*R(V) prior,
    # mean of 0.2*extinction prior.
    # nearby stars get an extinction prior of 0.
    # there really aren't many nearby stars (<100 pc; these are APOGEE
    # giants, so no surprise).  So let's just do |b| > 30, D > 1 kpc.
    m = (numpy.abs(ob['b']) > 30) & (ob['parallax'] < 1)
    extprior = numpy.zeros((len(ob), 2), dtype='f8')
    extpriorsig = numpy.zeros((len(ob), 2), dtype='f8')
    extprior[m, 0] = dust.getval(ob['l'][m], ob['b'][m], map='sfd')*avfac
    extpriorsig[m, 0] = 0.1*extprior[m, 0]
    extpriorsig[m, 0] = numpy.sqrt(extpriorsig[m, 0]**2. + (0.01*avfac)**2.)
    extpriorsig[~m, 0] = 30
    extpriorsig[m, 1] = extpriorsig[m, 0]
    extpriorsig[~m, 1] = 3
    # really rough guesses!
    return extprior, extpriorsig
Ejemplo n.º 3
0
def maketilefile(desitiles, gaiadensitymapfile, tycho2file):
    """Make tile file.
    
    Args:
        desitiles: original DESI tile file
        gaiadensitymapfile: file name of healpix map of density of Gaia 
            stars brighter than 19th mag.
        tycho2file: file name of list of ra, dec, bt, vt mags of Tycho-2
            stars.
    """
    import healpy
    nside = 512  # hack: needs to match gaianumdens map below.
    m0 = desitiles['pass'] == 0
    ran, decn = logradecoffscheme(desitiles['ra'][m0],
                                  desitiles['dec'][m0],
                                  dx=0.6,
                                  ang=24)
    # stupid way to make copy of an array, but most other things I tried
    # ended up with the dtype of desitilesnew being a reference to the dtype
    # of desitiles, which I didn't want.
    desitilesnew = numpy.zeros(len(desitiles), dtype=desitiles.dtype.descr)
    for n in desitilesnew.dtype.names:
        desitilesnew[n] = desitiles[n]
    desitilesnew.dtype.names = [n.lower() for n in desitilesnew.dtype.names]
    desitilesnew['ra'] = ran
    desitilesnew['dec'] = decn
    m0 = desitilesnew['pass'] == 0
    # pass 0 & 9: identical to centers in original and new schemes
    desitilesnew['in_desi'] = numpy.concatenate([desitilesnew['in_desi'][m0]] *
                                                10)
    # just repeat identically for each pass; all passes are close to
    # pass = 0 'centers'.
    theta, phi = healpy.pix2ang(nside, numpy.arange(12 * nside**2))
    la, ba = phi * 180. / numpy.pi, 90 - theta * 180. / numpy.pi
    try:
        from desitarget.mock import sfdmap
        ebva = sfdmap.ebv(la,
                          ba,
                          frame='galactic',
                          mapdir=os.getenv('DUST_DIR') + '/maps',
                          scaling=1)
    except:
        import dust
        ebva = dust.getval(la, ba, map='sfd')
    from astropy.coordinates import SkyCoord
    from astropy import units as u
    coord = SkyCoord(ra=ran * u.deg, dec=decn * u.deg, frame='icrs')
    coordgal = coord.galactic
    lt, bt = coordgal.l.value, coordgal.b.value
    uvt = lb2uv(lt, bt)
    from astropy.io import fits
    gaiadens = fits.getdata(gaiadensitymapfile).copy()
    fprad = 1.605

    for i in range(len(desitilesnew)):
        ind = healpy.query_disc(nside, uvt[i], fprad * numpy.pi / 180.)
        desitilesnew['ebv_med'][i] = numpy.median(ebva[ind])
        desitilesnew['star_density'][i] = numpy.median(gaiadens[ind])

    brightstars = fits.getdata(tycho2file)
    mb, mt, dbt = match_radec(brightstars['ra'], brightstars['dec'], ran, decn,
                              fprad)
    s = numpy.lexsort((brightstars['vtmag'][mb], mt))
    mt, mb, dbt = mt[s], mb[s], dbt[s]
    desitilesnew_add = numpy.zeros(len(ran),
                                   dtype=[('brightra', '3f8'),
                                          ('brightdec', '3f8'),
                                          ('brightvtmag', '3f4'),
                                          ('centerid', 'i4')])
    from numpy.lib import recfunctions
    desitilesnew = recfunctions.merge_arrays((desitilesnew, desitilesnew_add),
                                             flatten=True)
    for f, l in subslices(mt):
        end = numpy.clip(l - f, 0, 3)
        l = numpy.clip(l, f, f + 3)
        ind = mt[f]
        desitilesnew['brightra'][ind, 0:end] = brightstars['ra'][mb[f:l]]
        desitilesnew['brightdec'][ind, 0:end] = brightstars['dec'][mb[f:l]]
        desitilesnew['brightvtmag'][ind, 0:end] = brightstars['vtmag'][mb[f:l]]

    p = desitilesnew['pass']
    desitilesnew['program'][p == 0] = 'GRAY'
    desitilesnew['program'][(p >= 1) & (p <= 4)] = 'DARK'
    desitilesnew['program'][(p >= 5) & (p <= 7)] = 'BRIGHT'
    desitilesnew['program'][(p >= 8)] = 'EXTRA'
    obscondmapping = {'EXTRA': 0, 'DARK': 1, 'GRAY': 2, 'BRIGHT': 4}
    for program, obscond in obscondmapping.items():
        m = desitilesnew['program'] == program
        desitilesnew['obsconditions'][m] = obscond

    desitilesnew['airmass'] = airmass(
        numpy.ones(len(desitilesnew), dtype='f4') * 15., desitilesnew['dec'],
        31.96)
    signalfac = 10.**(3.303 * desitilesnew['ebv_med'] / 2.5)
    desitilesnew['exposefac'] = signalfac**2 * desitilesnew['airmass']**1.25
    desitilesnew['centerid'] = numpy.concatenate([desitilesnew['tileid'][m0]] *
                                                 10)
    return desitilesnew
Ejemplo n.º 4
0
def load_data(P_ref=0.52854, FeH_ref=-1.4):

    # load Table 2 of Dambis et al. (2013)
    dambis = getdata('Dambis_2013_Table2.fits')

    # load Table 1 of Klein & Bloom (2013)
    tbl = np.genfromtxt(
        'rrl_fit_table1.txt',
        names=
        'name, type, blazhko, period, log10(P_f/P_0), FeH, prior_mu, prior_mu_err, SF_ebv, SF_ebv_err, m_U_obs, m_U_obs_err, m_B_obs, m_B_obs_err, m_hipp_obs, m_hipp_obs_err, m_V_obs, m_V_obs_err, m_R_obs, m_R_obs_err, m_I_obs, m_I_obs_err, m_z_obs, m_z_obs_err, m_J_obs, m_J_obs_err, m_H_obs, m_H_obs_err, m_K_obs, m_K_obs_err, m_W1_obs, m_W1_obs_err, m_W2_obs, m_W2_obs_err, m_W3_obs, m_W3_obs_err, post_mu, post_mu_err',
        dtype=
        '|S10, |S5, bool, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8, f8',
        skip_header=1)
    tbl = append_fields(tbl,
                        names=('ra', 'dec', 'gl', 'gb', 'EBV', 'FeHErr',
                               'par_obs', 'sigma_par'),
                        data=(np.zeros(tbl.size), np.zeros(tbl.size),
                              np.zeros(tbl.size), np.zeros(tbl.size),
                              np.zeros(tbl.size), np.zeros(tbl.size) + 0.15,
                              np.zeros(tbl.size), np.zeros(tbl.size)),
                        usemask=False,
                        asrecarray=False)
    # uncertainty in [Fe/H] is 0.15 dex (Note 8 in Table 1 of Fernley et al. 1998)

    # remove spaces from Table 2 names
    for i, name in enumerate(dambis['Name']):
        dambis['Name'][i] = name.replace(' ', '')
        if dambis['Name'][i][0:2] == 'V0':
            dambis['Name'][i] = name.replace('V0', 'V').replace(' ', '')

    # match Table 2 and Table 1 to get positions of RR Lyrae stars
    for i, name in enumerate(tbl['name']):
        ind = np.where(name == dambis['Name'])[0]
        if ind.size > 0:
            tbl['ra'][i] = dambis['RAJ2000'][ind[0]]
            tbl['dec'][i] = dambis['DEJ2000'][ind[0]]
        else:
            print "Object %s has no data!" % name

    # add galactic coordinates
    gl, gb = eq2gal(tbl['ra'], tbl['dec'])
    tbl['gl'] = gl
    tbl['gb'] = gb

    # add extinction
    tbl['EBV'] = getval(tbl['gl'], tbl['gb'])

    # add TGAS parallaxes
    tgas = np.genfromtxt('tgas_match.txt', names=True)
    # back out TGAS uncertainty corrections
    tgas['parallax_error'] = np.sqrt(tgas['parallax_error']**2 - 0.2**2) / 1.4

    h = esutil.htm.HTM(10)
    m1, m2, d12 = h.match(tbl['ra'],
                          tbl['dec'],
                          tgas['ra'],
                          tgas['dec'],
                          5 / 3600.,
                          maxmatch=1)
    tbl['par_obs'][m1] = tgas['parallax'][m2] / 1000.
    tbl['sigma_par'][m1] = tgas['parallax_error'][m2] / 1000.
    tbl['ra'][m1] = tgas['ra'][m2]
    tbl['dec'][m1] = tgas['dec'][m2]

    # eliminate objects without TGAS parallaxes
    tbl = tbl[tbl['sigma_par'] <> 0]

    # define the PLRs (Table 2 of Klein & Bloom 2013)
    klein2014_table2 = np.genfromtxt('%s/Klein_et_al_2014_Table2.csv' %
                                     work_dir,
                                     delimiter=',',
                                     names=True,
                                     dtype='|S10,f8,f8,f8,f8,f8,f8,f8,f8')

    bands = klein2014_table2['band']
    alphas = klein2014_table2['alpha']
    betas = klein2014_table2['beta']
    gammas = np.array([
        0.5, 0.4, 0.3, 0.3, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.1, 0.1, 0.1
    ])
    #alphas[9] = -2.326 # K-band slope from Braga et al. (2015)
    alphas[9] = -2.38  # +- 0.04, from Sollima et al. (2006)
    gammas[9] = 0.09  # +- 0.14, from Sollima et al. (2006)
    #ax = (alphas[9]+0.04*np.random.randn(1000))*np.log10(P_ref) + (gammas[9] + 0.14*np.random.randn(1000))*FeH_ref -1.04 + 0.13*np.random.randn(1000)
    betas[9] = -0.50  # np.mean(ax)
    alphas[10] = -2.381  # +- 0.097, from Dambis et al. (2014)
    gammas[10] = 0.106  # +- 0.023, from Dambis et al. (2014)
    #ax = (alphas[10]+0.097*np.random.randn(1000))*np.log10(P_ref) + (gammas[10] + 0.023*np.random.randn(1000))*FeH_ref - 1.135 + 0.077*np.random.randn(1000)
    betas[10] = -0.62
    alphas[11] = -2.269  # +- 0.127, from Dambis et al. (2014)
    gammas[11] = 0.117  # +- 0.023, from Dambis et al. (2014)
    #ax = (alphas[11]+0.127*np.random.randn(1000))*np.log10(P_ref) + (gammas[11] + 0.023*np.random.randn(1000))*FeH_ref - 1.088 + 0.077*np.random.randn(1000)
    betas[11] = -0.62

    # set scatter in all PLRs to 0.001 mag to measure the uncertainty in recovered parameters
    sigma_PLRs = np.zeros(bands.size) + 0.001
    #sigma_PLRs = klein2014_table2['sig_intrinsic']

    #ext_coeffs = np.array([4.334, 3.626, 3.0, 2.742, 2.169, 1.505, 1.263, 0.709, 0.449, 0.302, 0.2, 0.1, 0.05])
    ext_coeffs = calculate_ext_coeffs(
        0
    ) * 0.96710433795664874  # A_band = C_band * E(g-r), following Schlafly et al. (2016); multiply by 0.96710433795664874 to get A_band = C_band * E(B-V)
    # uncertainty in extinction coefficients assuming sigma(x) = 0.02 or sigma(RV) = 0.18 and Schlafly et al. (2016) extinction curve
    ext_coeffs_unc = np.array([
        0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.12, 0.07, 0.04, 0.03, 0.01,
        0.001, 0.05
    ])

    obs_mags = np.zeros((tbl.size, bands.size))
    obs_magErrs = np.zeros((tbl.size, bands.size))

    Nstars = obs_mags.shape[0]
    Nbands = obs_mags.shape[1]

    for b, ext_coeff in enumerate(ext_coeffs):
        obs_mags[:, b] = tbl['m_%s_obs' % bands[b]]
        obs_magErrs[:, b] = tbl['m_%s_obs_err' % bands[b]]

    log10P_fP_0 = tbl['log10P_fP_0']
    EBV = tbl['EBV']

    # RIJHK: Table 2 of Braga et al. (2015)
    # alphas: R = -0.847 +- 0.177, I = -1.137 +- 0.144, J = -1.793 +- 0.109, H = -2.408 +- 0.082, K = -2.326 +- 0.074
    # W1, W2, W3: Eqs. 2-7 of Klein et al. (2014)
    # DM of M4 is 11.4 (Neeley et al. 2015)

    # Gaussian priors on betas, alphas, gammas, and sigma_PLRs from Table 2 of Klein et al. (2013)
    alpha_mean = klein2014_table2['alpha']
    alpha_sig = klein2014_table2['alpha_sig']
    #alpha_mean[9] = -2.326 # from Braga et al. (2015)
    #alpha_sig[9] = 0.074 # from Braga et al. (2015)
    alpha_mean[9] = -2.38  # from Sollima et al. (2006)
    alpha_sig[9] = 0.04  # from Sollima et al. (2006)
    alpha_mean[10] = -2.381  # from Dambis et al. (2014)
    alpha_sig[10] = 0.097  # from Dambis et al. (2014)
    alpha_mean[11] = -2.269  # from Dambis et al. (2014)
    alpha_sig[11] = 0.127  # from Dambis et al. (2014)
    beta_mean = klein2014_table2['beta']
    beta_sig = klein2014_table2['beta_sig']
    beta_mean[9] = -0.50
    beta_sig[9] = 0.23
    beta_mean[10] = -0.62
    beta_sig[10] = 0.09
    beta_mean[11] = -0.62
    beta_sig[11] = 0.09
    gamma_mean = gammas
    gamma_sig = gammas * 0 + 0.14
    gamma_mean[10] = 0.106  # from Dambis et al. (2014)
    gamma_sig[10] = 0.023  # from Dambis et al. (2014)
    gamma_mean[11] = 0.117  # from Dambis et al. (2014)
    gamma_sig[11] = 0.023  # from Dambis et al. (2014)
    #sigma_PLR_mean = klein2014_table2['sig_intrinsic']
    #sigma_PLR_sig = klein2014_table2['sig_intrinsic_sig']
    sigma_PLR_mean = np.zeros(bands.size) + 0.001
    sigma_PLR_sig = np.zeros(bands.size) + 0.0001

    # hard limits on PLR parameters, mean +- 7*sigma
    alphas_lower_limit = []
    alphas_upper_limit = []
    for alpha, sig in zip(alpha_mean, alpha_sig):
        alphas_lower_limit.append(alpha - 7 * sig)
        alphas_upper_limit.append(alpha + 7 * sig)

    alphas_lower_limit = np.array(alphas_lower_limit)
    alphas_upper_limit = np.array(alphas_upper_limit)

    betas_lower_limit = []
    betas_upper_limit = []
    for beta, sig in zip(beta_mean, beta_sig):
        betas_lower_limit.append(beta - 7 * sig)
        betas_upper_limit.append(beta + 7 * sig)

    betas_lower_limit = np.array(betas_lower_limit)
    betas_upper_limit = np.array(betas_upper_limit)

    # use broad priors for the W1 and W2 bands
    alphas_upper_limit[10:12] = 2
    alphas_lower_limit[10:12] = -5
    betas_upper_limit[10:12] = 0
    betas_lower_limit[10:12] = -4

    # use broad priors for the Hipparcos band
    alphas_upper_limit[2] = 2
    alphas_lower_limit[2] = -5
    betas_upper_limit[2] = 2
    betas_lower_limit[2] = -2

    # this prior is not used right now
    sig_PLR_lower_limit = []
    sig_PLR_upper_limit = []
    for sig_PLR, sig in zip(sigma_PLR_mean, sigma_PLR_sig):
        sig_PLR_lower_limit.append(sig_PLR - 5 * sig)
        sig_PLR_upper_limit.append(sig_PLR + 5 * sig)

    sig_PLR_lower_limit = np.array(sig_PLR_lower_limit)
    sig_PLR_lower_limit = np.where(sig_PLR_lower_limit <= 0, 0.00001,
                                   sig_PLR_lower_limit)
    sig_PLR_upper_limit = np.array(sig_PLR_upper_limit)

    # dump all important data
    dat = {}
    dat['scenario'] = 'real'
    dat['name'] = tbl['name']
    dat['ra'] = tbl['ra']
    dat['dec'] = tbl['dec']
    dat['P_ref'] = P_ref
    dat['type'] = tbl['type']
    dat['blazhko'] = tbl['blazhko']
    dat['FeH_ref'] = FeH_ref
    dat['obs_mags'] = obs_mags
    dat['obs_magErrs'] = obs_magErrs
    dat['par_obs'] = tbl['par_obs']
    dat['sigma_par'] = tbl['sigma_par']
    dat['log10P_fP_0'] = log10P_fP_0
    dat['EBV'] = EBV
    dat['FeH'] = tbl['FeH']
    dat['FeHErr'] = tbl['FeHErr']
    dat['alphas_lower_limit'] = alphas_lower_limit
    dat['alphas_upper_limit'] = alphas_upper_limit
    dat['betas_lower_limit'] = betas_lower_limit
    dat['betas_upper_limit'] = betas_upper_limit
    dat['sig_PLR_lower_limit'] = sig_PLR_lower_limit
    dat['sig_PLR_upper_limit'] = sig_PLR_upper_limit
    dat['alpha_mean'] = alpha_mean
    dat['alpha_sig'] = alpha_sig
    dat['beta_mean'] = beta_mean
    dat['beta_sig'] = beta_sig
    dat['gamma_mean'] = gamma_mean
    dat['gamma_sig'] = gamma_sig
    dat['sigma_PLR_mean'] = sigma_PLR_mean
    dat['sigma_PLR_sig'] = sigma_PLR_sig
    dat['ext_coeffs'] = ext_coeffs
    dat['ext_coeffs_unc'] = ext_coeffs_unc
    with gzip.open('TGAS_data.pklz', 'wb') as f:
        cPickle.dump(dat, f)

    return dat
Ejemplo n.º 5
0
def maketilefile(desitiles, gaiadensitymapfile, tycho2file):
    """Make tile file.
    
    Args:
        desitiles: original DESI tile file
        gaiadensitymapfile: file name of healpix map of density of Gaia 
            stars brighter than 19th mag.
        tycho2file: file name of list of ra, dec, bt, vt mags of Tycho-2
            stars.
    """
    import healpy
    nside = 512  # hack: needs to match gaianumdens map below.
    m0 = desitiles['pass'] == 0
    ran, decn = logradecoffscheme(desitiles['ra'][m0], 
                                  desitiles['dec'][m0], dx=0.6, ang=24)
    # stupid way to make copy of an array, but most other things I tried
    # ended up with the dtype of desitilesnew being a reference to the dtype
    # of desitiles, which I didn't want.
    desitilesnew = numpy.zeros(len(desitiles), dtype=desitiles.dtype.descr)
    for n in desitilesnew.dtype.names:
        desitilesnew[n] = desitiles[n]
    desitilesnew.dtype.names = [n.lower() for n in desitilesnew.dtype.names]
    desitilesnew['ra'] = ran
    desitilesnew['dec'] = decn
    m0 = desitilesnew['pass'] == 0
    # pass 0 & 9: identical to centers in original and new schemes
    desitilesnew['in_desi'] = numpy.concatenate(
        [desitilesnew['in_desi'][m0]]*10)
    # just repeat identically for each pass; all passes are close to
    # pass = 0 'centers'.
    theta, phi = healpy.pix2ang(nside, numpy.arange(12*nside**2))
    la, ba = phi*180./numpy.pi, 90-theta*180./numpy.pi
    try:
        from desitarget.mock import sfdmap
        ebva = sfdmap.ebv(la, ba, frame='galactic', 
                          mapdir=os.getenv('DUST_DIR')+'/maps', scaling=1)
    except:
        import dust
        ebva = dust.getval(la, ba, map='sfd')
    from astropy.coordinates import SkyCoord
    from astropy import units as u
    coord = SkyCoord(ra=ran*u.deg, dec=decn*u.deg, frame='icrs')
    coordgal = coord.galactic
    lt, bt = coordgal.l.value, coordgal.b.value
    uvt = lb2uv(lt, bt)
    from astropy.io import fits
    gaiadens = fits.getdata(gaiadensitymapfile).copy()
    fprad = 1.605
    
    for i in range(len(desitilesnew)):
        ind = healpy.query_disc(nside, uvt[i], fprad*numpy.pi/180.)
        desitilesnew['ebv_med'][i] = numpy.median(ebva[ind])
        desitilesnew['star_density'][i] = numpy.median(gaiadens[ind])

    brightstars = fits.getdata(tycho2file)
    mb, mt, dbt = match_radec(brightstars['ra'], brightstars['dec'], 
                              ran, decn, fprad)
    s = numpy.lexsort((brightstars['vtmag'][mb], mt))
    mt, mb, dbt = mt[s], mb[s], dbt[s]
    desitilesnew_add = numpy.zeros(len(ran), dtype=[
            ('brightra', '3f8'), ('brightdec', '3f8'), ('brightvtmag', '3f4'),
            ('centerid', 'i4')])
    from numpy.lib import recfunctions
    desitilesnew = recfunctions.merge_arrays((desitilesnew, desitilesnew_add),
                                             flatten=True)
    for f, l in subslices(mt):
        end = numpy.clip(l-f, 0, 3)
        l = numpy.clip(l, f, f+3)
        ind = mt[f]
        desitilesnew['brightra'][ind, 0:end] = brightstars['ra'][mb[f:l]]
        desitilesnew['brightdec'][ind, 0:end] = brightstars['dec'][mb[f:l]]
        desitilesnew['brightvtmag'][ind, 0:end] = brightstars['vtmag'][mb[f:l]]

    p = desitilesnew['pass']
    desitilesnew['program'][p == 0] = 'GRAY'
    desitilesnew['program'][(p >= 1) & (p <= 4)] = 'DARK'
    desitilesnew['program'][(p >= 5) & (p <= 7)] = 'BRIGHT'
    desitilesnew['program'][(p >= 8)] = 'EXTRA'
    obscondmapping = {'EXTRA': 0, 'DARK': 1, 'GRAY': 2, 'BRIGHT': 4}
    for program, obscond in obscondmapping.items():
        m = desitilesnew['program'] == program
        desitilesnew['obsconditions'][m] = obscond
    
    desitilesnew['airmass'] = airmass(
        numpy.ones(len(desitilesnew), dtype='f4')*15., desitilesnew['dec'],
        31.96)
    signalfac = 10.**(3.303*desitilesnew['ebv_med']/2.5)
    desitilesnew['exposefac'] = signalfac**2 * desitilesnew['airmass']**1.25
    desitilesnew['centerid'] = numpy.concatenate(
        [desitilesnew['tileid'][m0]]*10)
    return desitilesnew