def make_observed_isochrone_hst_test(logAge, AKs=defaultAKs, k=3,
                                     distance=defaultDist, verbose=False):

    redlaw_k = RedLawNishiyama09(k=k)
    isoDir = 'iso_k{0}'.format(k)
    
    startTime = time.time()

    print('Making isochrone: log(t) = %.2f  AKs = %.2f  dist = %d' % \
        (logAge, AKs, distance))
    print('     Starting at: ', datetime.datetime.now(), '  Usually takes ~5 minutes')

    outFile = '/u/jlu/work/wd1/models/' + isoDir + '/'
    outFile += 'iso_%.2f_hst_%4.2f_%4s.pickle' % (logAge, AKs,
                                                 str(distance).zfill(4))

    c = constants

    # Get solar mettalicity models for a population at a specific age.
    evol = evolution.get_merged_isochrone(logAge=logAge)

    # Lets do some trimming down to get rid of repeat masses or 
    # mass resolutions higher than 1/1000. We will just use the first
    # unique mass after rounding by the nearest 0.001.
    mass_rnd = np.copy(evol.mass)

    idx = np.where(evol.mass > 10)[0]
    mass_rnd[idx] = np.round(evol.mass[idx], decimals=0)
    print(mass_rnd[0:10])

    mass_rnd = np.round(mass_rnd, decimals=1)
    print(mass_rnd[0:10])

    tmp, idx = np.unique(mass_rnd, return_index=True)
    print('Number of stars {0}'.format(len(idx)))

    mass = evol.mass[idx]
    logT = evol.logT[idx]
    logg = evol.logg[idx]
    logL = evol.logL[idx]
    isWR = logT != evol.logT_WR[idx]

    temp = 10**logT

    # Output magnitudes for each temperature and extinction value.
    mag814w = np.zeros(len(temp), dtype=float)
    mag125w = np.zeros(len(temp), dtype=float)
    mag139m = np.zeros(len(temp), dtype=float)
    mag160w = np.zeros(len(temp), dtype=float)

    filt814w = get_filter_info('acs,f814w,wfc1')
    filt125w = get_filter_info('wfc3,ir,f125w')
    filt139m = get_filter_info('wfc3,ir,f139m')
    filt160w = get_filter_info('wfc3,ir,f160w')

    # Make reddening
    red814w = redlaw_k.reddening(AKs).resample(filt814w.wave)
    red125w = redlaw_k.reddening(AKs).resample(filt125w.wave)
    red139m = redlaw_k.reddening(AKs).resample(filt139m.wave)
    red160w = redlaw_k.reddening(AKs).resample(filt160w.wave)

    # Convert luminosity to erg/s
    L_all = 10**(logL) * c.Lsun # luminsoity in erg/s

    # Calculate radius
    R_all = np.sqrt(L_all / (4.0 * math.pi * c.sigma * temp**4))
    R_all /= (c.cm_in_AU * c.AU_in_pc)

    # For each temperature extract the synthetic photometry.
    for ii in range(len(temp)):
        gravity = logg[ii]
        L = L_all[ii] # in erg/s
        T = temp[ii]  # in Kelvin
        R = R_all[ii] # in pc

        # Get the atmosphere model now. Wavelength is in Angstroms
        star = atm.get_merged_atmosphere(temperature=T, 
                                         gravity=gravity)

        # Trim wavelength range down to JHKL range (0.5 - 4.25 microns)
        star = spectrum.trimSpectrum(star, 5000, 42500)

        # Convert into flux observed at Earth (unreddened)
        star *= (R / distance)**2  # in erg s^-1 cm^-2 A^-1

        # ----------
        # Now to the filter integrations
        # ----------
        mag814w[ii] = mag_in_filter(star, filt814w, red814w)
        mag125w[ii] = mag_in_filter(star, filt125w, red125w)
        mag139m[ii] = mag_in_filter(star, filt139m, red139m)
        mag160w[ii] = mag_in_filter(star, filt160w, red160w)

        if verbose:
            print('M = %7.3f Msun  T = %5d K  R = %2.1f Rsun  logg = %4.2f  F814W = %4.2f  F125W = %4.2f  F139M = %4.2f  F160W = %4.2f' % \
                (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii], mag814w[ii], mag125w[ii], mag139m[ii], mag160w[ii]))


    iso = objects.DataHolder()
    iso.M = mass
    iso.T = temp
    iso.logg = logg
    iso.logL = logL
    iso.mag814w = mag814w
    iso.mag125w = mag125w
    iso.mag139m = mag139m
    iso.mag160w = mag160w
    iso.isWR = isWR
    
    _out = open(outFile, 'wb')
    pickle.dump(mass, _out)
    pickle.dump(temp, _out)
    pickle.dump(logg, _out)
    pickle.dump(logL, _out)
    pickle.dump(mag814w, _out)
    pickle.dump(mag125w, _out)
    pickle.dump(mag139m, _out)
    pickle.dump(mag160w, _out)
    pickle.dump(isWR, _out)
    _out.close()

    endTime = time.time()
    print('      Time taken: %d seconds' % (endTime - startTime))
def make_observed_isochrone_hst(logAge, AKs=defaultAKs,
                                distance=defaultDist, verbose=False,
                                massSampling=10):
    """
    massSampling - Sample the raw isochrone every ## steps. The default
                   is massSampling = 10, which takes every 10th point.
                   The isochrones are already very finely sampled. Must be
                   an integer value.
    """
    startTime = time.time()

    print 'Making isochrone: log(t) = %.2f  AKs = %.2f  dist = %d' % \
        (logAge, AKs, distance)
    print '     Starting at: ', datetime.datetime.now(), '  Usually takes ~5 minutes'

    # outFile = '/u/mwhosek/Desktop/699-2/isochrones/'
    outFile = '/u/jlu/work/arches/models/iso/'
    outFile += 'iso_%.2f_hst_%4.2f_%4s.pickle' % (logAge, AKs,
                                                 str(distance).zfill(4))

    c = constants

    # Get solar mettalicity models for a population at a specific age.
    evol = evolution.get_merged_isochrone(logAge=logAge)
    print 'Elapsed time while getting merged isochrone: ', time.time() - startTime

    #Eliminate cases where log g is less than 0
    idx = np.where(evol.logg > 0)
    
    mass = evol.mass[idx]
    logT = evol.logT[idx]
    logg = evol.logg[idx]
    logL = evol.logL[idx]
    isWR = logT != evol.logT_WR[idx]

    mass = mass[::massSampling]
    logT = logT[::massSampling]
    logg = logg[::massSampling]
    logL = logL[::massSampling]
    isWR = isWR[::massSampling]
    
    temp = 10**logT

    # Output magnitudes for each temperature and extinction value.
    mag814w = np.zeros(len(temp), dtype=float)
    mag127m = np.zeros(len(temp), dtype=float)
    mag139m = np.zeros(len(temp), dtype=float)
    mag153m = np.zeros(len(temp), dtype=float)
    magJ = np.zeros(len(temp), dtype=float)
    magH = np.zeros(len(temp), dtype=float)
    magK = np.zeros(len(temp), dtype=float)
    magKp = np.zeros(len(temp), dtype=float)
    magLp = np.zeros(len(temp), dtype=float)

    filt814w = get_filter_info('wfc3,uvis1,f814w')
    filt127m = get_filter_info('wfc3,ir,f127m')
    filt139m = get_filter_info('wfc3,ir,f139m')
    filt153m = get_filter_info('wfc3,ir,f153m')
    filtJ = get_filter_info('nirc2,J')
    filtH = get_filter_info('nirc2,H')
    filtK = get_filter_info('nirc2,K')
    filtKp = get_filter_info('nirc2,Kp')
    filtLp = get_filter_info('nirc2,Lp')

    # Make reddening
    red814w = redlaw.reddening(AKs).resample(filt814w.wave)
    red127m = redlaw.reddening(AKs).resample(filt127m.wave)
    red139m = redlaw.reddening(AKs).resample(filt139m.wave)
    red153m = redlaw.reddening(AKs).resample(filt153m.wave)
    redJ = redlaw.reddening(AKs).resample(filtJ.wave)
    redH = redlaw.reddening(AKs).resample(filtH.wave)
    redK = redlaw.reddening(AKs).resample(filtK.wave)
    redKp = redlaw.reddening(AKs).resample(filtKp.wave)
    redLp = redlaw.reddening(AKs).resample(filtLp.wave)

    # Convert luminosity to erg/s
    L_all = 10**(logL) * c.Lsun # luminsoity in erg/s

    # Calculate radius
    R_all = np.sqrt(L_all / (4.0 * math.pi * c.sigma * temp**4))
    R_all /= (c.cm_in_AU * c.AU_in_pc)

    # For each temperature extract the synthetic photometry.
    for ii in range(len(temp)):
        gravity = logg[ii]
        L = L_all[ii] # in erg/s
        T = temp[ii]  # in Kelvin
        R = R_all[ii] # in pc

        # Get the atmosphere model now. Wavelength is in Angstroms
        star = atm.get_phoenix_atmosphere(temperature=T, 
                                         gravity=gravity)

        # Trim wavelength range down to JHKL range (0.5 - 4.25 microns)
        star = spectrum.trimSpectrum(star, 5000, 42500)

        # Convert into flux observed at Earth (unreddened)
        star *= (R / distance)**2  # in erg s^-1 cm^-2 A^-1

        # ----------
        # Now to the filter integrations
        # ----------
        mag814w[ii] = mag_in_filter(star, filt814w, red814w)
        mag127m[ii] = mag_in_filter(star, filt127m, red127m)
        mag139m[ii] = mag_in_filter(star, filt139m, red139m)
        mag153m[ii] = mag_in_filter(star, filt153m, red153m)
        magJ[ii] = mag_in_filter(star, filtJ, redJ)
        magH[ii] = mag_in_filter(star, filtH, redH)
        magK[ii] = mag_in_filter(star, filtK, redK)
        magKp[ii] = mag_in_filter(star, filtKp, redKp)
        magLp[ii] = mag_in_filter(star, filtLp, redLp)

        if verbose:
            print 'M = %7.3f Msun  T = %5d K  R = %2.1f Rsun  logg = %4.2f  F127M = %4.2f  F139M = %4.2f  F153M = %4.2f elapsed time = %4s' % \
                (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii], mag127m[ii], mag139m[ii], mag153m[ii], time.time() - startTime)


    iso = objects.DataHolder()
    iso.M = mass
    iso.T = temp
    iso.logg = logg
    iso.logL = logL
    iso.mag127m = mag127m
    iso.mag139m = mag139m
    iso.mag153m = mag153m
    iso.magJ = magJ
    iso.magH = magH
    iso.magK = magK
    iso.magKp = magKp
    iso.magLp = magLp
    iso.isWR = isWR
    iso.mag814w = mag814w
    
    _out = open(outFile, 'wb')
    pickle.dump(mass, _out)
    pickle.dump(temp, _out)
    pickle.dump(logg, _out)
    pickle.dump(logL, _out)
    pickle.dump(mag127m, _out)
    pickle.dump(mag139m, _out)
    pickle.dump(mag153m, _out)
    pickle.dump(magJ, _out)
    pickle.dump(magH, _out)
    pickle.dump(magK, _out)
    pickle.dump(magKp, _out)
    pickle.dump(magLp, _out)
    pickle.dump(isWR, _out)
    pickle.dump(mag814w, _out)
    _out.close()

    endTime = time.time()
    print '      Time taken: %d seconds' % (endTime - startTime)
def nearIR(distance, logAge, redlawClass=RedLawNishiyama09, AKsGrid=None):
    """
    For a sampling of effective temperatures and extinctions, calculate the
    J, H, K, Kp, Ks, Lp magnitudes for a population at the specified
    distance and age. All output is stored in a pickle file.

    Input Parameters:
    distance in pc
    logAge

    Optional Input Parameters:
    redlawClass - default = RedLawNishiyama09
    AKsGrid -- default [0 - 5; 0.1 steps]

    Output stored in a pickle file named syn_nir_d#####_a####.dat.
    
    """
    pickleFile = 'syn_nir_d' + str(distance).zfill(5) + '_a' \
        + str(int(round(logAge*100))).zfill(3) + '.dat'

    # Get solar mettalicity models for a population at a specific age.
    evol = evolution.get_merged_isochrone(logAge=logAge)
    mass = evol.mass
    logT = evol.logT
    logg = evol.logg
    logL = evol.logL
    temp = 10**logT
    isWR = evol.logT != evol.logT_WR
    print 'nearIR: Getting rid of Wolf-Rayet stars, we cannot model their atmospheres'

    # First get rid of the WR stars, we can't connect atmospheres
    # to them anyhow.
    idx = np.where(isWR == False)[0]
    mass = mass[idx]
    logT = logT[idx]
    logg = logg[idx]
    logL = logL[idx]
    temp = temp[idx]
    isWR = isWR[idx]
    
    # Sample only 100 points along the whole isochrone
    interval = int(math.floor(len(mass) / 100.0))
    idx = np.arange(0, len(mass), interval, dtype=int)
    # Make sure to get the last point
    if idx[-1] != (len(mass) - 1):
        idx = np.append(idx, len(mass) - 1)
        
    mass = mass[idx]
    logT = logT[idx]
    logg = logg[idx]
    logL = logL[idx]
    temp = temp[idx]

    # We will also run through a range of extinctions
    if AKsGrid == None:
        AKsGrid = np.arange(0, 5, 0.1)

    # Fetch earth, vega, and extinction objects
    earth = EarthAtmosphere()
    vega = Vega()
    redlaw = redlawClass()

    # Get the transmission curve for NIRC2 filters and atmosphere.
    J_filter, J_flux0, J_mag0 = get_filter_info('J', earth, vega)
    H_filter, H_flux0, H_mag0 = get_filter_info('H', earth, vega)
    K_filter, K_flux0, K_mag0 = get_filter_info('K', earth, vega)
    Kp_filter, Kp_flux0, Kp_mag0 = get_filter_info('Kp', earth, vega)
    Ks_filter, Ks_flux0, Ks_mag0 = get_filter_info('Ks', earth, vega)
    Lp_filter, Lp_flux0, Lp_mag0 = get_filter_info('Lp', earth, vega)

    # Output magnitudes for each temperature and extinction value.
    J = np.zeros((len(temp), len(AKsGrid)), dtype=float)
    H = np.zeros((len(temp), len(AKsGrid)), dtype=float)
    K = np.zeros((len(temp), len(AKsGrid)), dtype=float)
    Kp = np.zeros((len(temp), len(AKsGrid)), dtype=float)
    Ks = np.zeros((len(temp), len(AKsGrid)), dtype=float)
    Lp = np.zeros((len(temp), len(AKsGrid)), dtype=float)

    # For each filter, lets pre-make reddening curves so we only
    # have to do the calculation once.
    J_red = []
    H_red = []
    K_red = []
    Kp_red = []
    Ks_red = []
    Lp_red = []
    
    print 'Making extinction curves'
    for aa in range(len(AKsGrid)):
        red = redlaw.reddening(AKsGrid[aa])

        J_red.append( red.resample(J_filter.wave) )
        H_red.append( red.resample(H_filter.wave) )
        K_red.append( red.resample(K_filter.wave) )
        Kp_red.append( red.resample(Kp_filter.wave) )
        Ks_red.append( red.resample(Ks_filter.wave) )
        Lp_red.append( red.resample(Lp_filter.wave) )
    
    # For each temperature extract the synthetic photometry.
    for ii in range(len(temp)):
        gravity = logg[ii]
        L = 10**(logL[ii]) * c.Lsun # luminosity in erg/s
        T = temp[ii]  # in Kelvin
        # Get the radius
        R = math.sqrt(L / (4.0 * math.pi * c.sigma * T**4))   # in cm
        R /= (c.cm_in_AU * c.AU_in_pc)   # in pc

        print 'M = %6.2f Msun   T = %5d   R = %2.1f Rsun   logg = %4.2f' % \
            (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii])

        # Get the atmosphere model now. Wavelength is in Angstroms
        star = atm.get_merged_atmosphere(temperature=T,
                                         gravity=gravity)

        # Trim wavelength range down to JHKL range (1.0 - 4.25 microns)
        star = spectrum.trimSpectrum(star, 10000, 42500)

        # Convert into flux observed at Earth (unreddened)
        star *= (R / distance)**2  # in erg s^-1 cm^-2 A^-1

        for aa in range(len(AKsGrid)):
            print 'Photometry for T = %5d, AKs = %3.1f' % \
                (temp[ii], AKsGrid[aa])
            
            # ----------
            # Now to the filter integrations
            # ----------
            # K
            J[ii, aa] = mag_in_filter(star, J_filter, J_red[aa], 
                                      J_flux0, J_mag0)
            H[ii, aa] = mag_in_filter(star, H_filter, H_red[aa], 
                                      H_flux0, H_mag0)
            K[ii, aa] = mag_in_filter(star, K_filter, K_red[aa], 
                                      K_flux0, K_mag0)
            Kp[ii, aa] = mag_in_filter(star, Kp_filter, Kp_red[aa], 
                                       Kp_flux0, Kp_mag0)
            Ks[ii, aa] = mag_in_filter(star, Ks_filter, Ks_red[aa], 
                                       Ks_flux0, Ks_mag0)
            Lp[ii, aa] = mag_in_filter(star, Lp_filter, Lp_red[aa], 
                                       Lp_flux0, Lp_mag0)


    # Save output to pickle file
    pf = open(pickleFile, 'w')
    pickle.dump(mass, pf)
    pickle.dump(logg, pf)
    pickle.dump(logL, pf)
    pickle.dump(temp, pf)
    pickle.dump(AKsGrid, pf)
    pickle.dump(J, pf)
    pickle.dump(H, pf)
    pickle.dump(K, pf)
    pickle.dump(Kp, pf)
    pickle.dump(Ks, pf)
    pickle.dump(Lp, pf)

    return pickleFile
def make_observed_isochrone_hst(logAge, AKs=defaultAKs,
                                distance=defaultDist, verbose=False):
    startTime = time.time()

    print 'Making isochrone: log(t) = %.2f  AKs = %.2f  dist = %d' % \
        (logAge, AKs, distance)
    print '     Starting at: ', datetime.datetime.now(), '  Usually takes ~5 minutes'

    outFile = '/u/jlu/work/arches/models/iso/'
    outFile += 'iso_%.2f_hst_%4.2f_%4s.pickle' % (logAge, AKs,
                                                 str(distance).zfill(4))

    c = constants

    # Get solar mettalicity models for a population at a specific age.
    evol = evolution.get_merged_isochrone(logAge=logAge)

    # Lets do some trimming down to get rid of repeat masses or 
    # mass resolutions higher than 1/1000. We will just use the first
    # unique mass after rounding by the nearest 0.001.
    mass_rnd = np.round(evol.mass, decimals=2)
    tmp, idx = np.unique(mass_rnd, return_index=True)

    mass = evol.mass[idx]
    logT = evol.logT[idx]
    logg = evol.logg[idx]
    logL = evol.logL[idx]
    isWR = logT != evol.logT_WR[idx]

    temp = 10**logT

    # Output magnitudes for each temperature and extinction value.
    mag127m = np.zeros(len(temp), dtype=float)
    mag139m = np.zeros(len(temp), dtype=float)
    mag153m = np.zeros(len(temp), dtype=float)
    magH = np.zeros(len(temp), dtype=float)
    magKp = np.zeros(len(temp), dtype=float)
    magLp = np.zeros(len(temp), dtype=float)

    filt127m = get_filter_info('wfc3,ir,f127m')
    filt139m = get_filter_info('wfc3,ir,f139m')
    filt153m = get_filter_info('wfc3,ir,f153m')
    filtH = get_filter_info('nirc2,H')
    filtKp = get_filter_info('nirc2,Kp')
    filtLp = get_filter_info('nirc2,Lp')

    # Make reddening
    red127m = redlaw.reddening(AKs).resample(filt127m.wave)
    red139m = redlaw.reddening(AKs).resample(filt139m.wave)
    red153m = redlaw.reddening(AKs).resample(filt153m.wave)
    redH = redlaw.reddening(AKs).resample(filtH.wave)
    redKp = redlaw.reddening(AKs).resample(filtKp.wave)
    redLp = redlaw.reddening(AKs).resample(filtLp.wave)

    # Convert luminosity to erg/s
    L_all = 10**(logL) * c.Lsun # luminsoity in erg/s

    # Calculate radius
    R_all = np.sqrt(L_all / (4.0 * math.pi * c.sigma * temp**4))
    R_all /= (c.cm_in_AU * c.AU_in_pc)

    # For each temperature extract the synthetic photometry.
    for ii in range(len(temp)):
        gravity = logg[ii]
        L = L_all[ii] # in erg/s
        T = temp[ii]  # in Kelvin
        R = R_all[ii] # in pc

        # Get the atmosphere model now. Wavelength is in Angstroms
        star = atm.get_merged_atmosphere(temperature=T, 
                                         gravity=gravity)

        # Trim wavelength range down to JHKL range (0.5 - 4.25 microns)
        star = spectrum.trimSpectrum(star, 5000, 42500)

        # Convert into flux observed at Earth (unreddened)
        star *= (R / distance)**2  # in erg s^-1 cm^-2 A^-1

        # ----------
        # Now to the filter integrations
        # ----------
        mag127m[ii] = mag_in_filter(star, filt127m, red127m)
        mag139m[ii] = mag_in_filter(star, filt139m, red139m)
        mag153m[ii] = mag_in_filter(star, filt153m, red153m)
        magH[ii] = mag_in_filter(star, filtH, redH)
        magKp[ii] = mag_in_filter(star, filtKp, redKp)
        magLp[ii] = mag_in_filter(star, filtLp, redLp)

        if verbose:
            print 'M = %7.3f Msun  T = %5d K  R = %2.1f Rsun  logg = %4.2f  F127M = %4.2f  F139M = %4.2f  F153M = %4.2f' % \
                (mass[ii], T, R * c.AU_in_pc / c.Rsun, logg[ii], mag127m[ii], mag139m[ii], mag153m[ii])


    iso = objects.DataHolder()
    iso.M = mass
    iso.T = temp
    iso.logg = logg
    iso.logL = logL
    iso.mag127m = mag127m
    iso.mag139m = mag139m
    iso.mag153m = mag153m
    iso.magH = magH
    iso.magKp = magKp
    iso.magLp = magLp
    iso.isWR = isWR
    
    _out = open(outFile, 'wb')
    pickle.dump(mass, _out)
    pickle.dump(temp, _out)
    pickle.dump(logg, _out)
    pickle.dump(logL, _out)
    pickle.dump(mag127m, _out)
    pickle.dump(mag139m, _out)
    pickle.dump(mag153m, _out)
    pickle.dump(magH, _out)
    pickle.dump(magKp, _out)
    pickle.dump(magLp, _out)
    pickle.dump(isWR, _out)
    _out.close()

    endTime = time.time()
    print '      Time taken: %d seconds' % (endTime - startTime)