예제 #1
0
    teff, logg = get_teff_logg(filename)
    koester_spectrum = pd.read_csv(
        filename,
        delim_whitespace=True,
        comment='#',
        names=['WAVELENGTH (ANGSTROM)', 'FLUX (ERG/CM2/S/A)']
    )

    # drop duplicate wavelengths. WTF are they here Koester?
    koester_spectrum.drop_duplicates(subset='WAVELENGTH (ANGSTROM)', inplace=True)

    # create pysynphot spectrum
    sp = S.ArraySpectrum(
        koester_spectrum['WAVELENGTH (ANGSTROM)'],
        koester_spectrum['FLUX (ERG/CM2/S/A)'],
        fluxunits='flam',
        waveunits='Angstroms'
    )

    # Set the lightpath for the hcam observations
    S.setref(**getref(hcam_tel))

    # Get all the hcam magnitudes
    simulated_mags = {}
    for f in hcam_filters:
        bp = S.ObsBandpass("{},{},{}".format('hcam',hcam_tel, f))
        obs = S.Observation(sp, bp, force='taper')
        mag = obs.effstim("abmag")
        simulated_mags['hcam_{}'.format(f)] = mag

    # Get the actual colours
예제 #2
0
def subtract_continuum(line='f673n',
                       cont='f814w',
                       target='galaxy',
                       file_name='galaxy*.fits',
                       line_name='ha',
                       z=0.02,
                       plot=False):
    """
    Function for subtracting the continuum in a line emission image

    INPUTS:
         line: Filter into which the emission line falls.
         cont: Filter within which the emission line and broader continuum are contained.
       target: The name of the target, to be used in the output files.
    file_name: General form of the file names that contain the line and continuum images.
    line_name: State 'ha' or 'pab' to subtract Balmer-alpha or Paschen-beta respectively.
            z: Redshift of the target object.
       
    KEYWORDS:
         PLOT: Set this keyword to produce a plot of the two-dimensional
               continuum subtracted image.   
    OUTPUTS:
         Fits file with the continuum subtracted line emission image.

    """

    import pysynphot as S
    import numpy as np
    import glob
    from grizli import utils
    import astropy.io.fits as pyfits
    import matplotlib.pyplot as plt

    # restframe wavelength of the emission lines to subtract
    wave_pab = 1.2822e4
    wave_ha = 6562.8

    print('Target =', target)
    files = glob.glob(file_name)
    files.sort()
    images = {}
    headers = {}
    bandpasses = {}

    for file in files:
        im = pyfits.open(file)
        filt = utils.get_hst_filter(im[0].header).lower()
        for ext in [0, 1]:
            if 'PHOTMODE' in im[ext].header:
                photflam = im[ext].header['PHOTFLAM']
                headers[filt.lower()] = im[ext].header
                bandpasses[filt.lower()] = S.ObsBandpass(
                    im[ext].header['PHOTMODE'].replace(' ', ','))
                break

        flat_flam = S.FlatSpectrum(1., fluxunits='flam')
        obs = S.Observation(flat_flam, bandpasses[filt.lower()])
        my_photflam = 1 / obs.countrate()
        flat_ujy = S.FlatSpectrum(1, fluxunits='ujy')
        obs = S.Observation(flat_ujy, bandpasses[filt.lower()])
        my_photfnu = 1 / obs.countrate()
        images[filt.lower()] = [im['SCI'].data, im['ERR'].data]

    # Use PySynphot to compute flux calibration factors

    if line_name == 'pab':
        # Pa-beta
        cont_filter, line_filter, line_wave, name = cont, line, wave_pab, 'pab'
    elif line_name == 'ha':
        # H-alpha
        cont_filter, line_filter, line_wave, name = cont, line, wave_ha, 'ha'

    ################
    # Continuum - flat spectrum
    cont = S.FlatSpectrum(1.e-19, fluxunits='flam')

    ###############
    # Continuum - slope spectrum
    cont_wave = np.arange(1000, 2.e4)

    slope = 0  # flat
    slope = 1  # red slope, increasing toward longer wavelengths
    cont_flux = (cont_wave / 1.e4)**slope
    cont = S.ArraySpectrum(cont_wave, cont_flux, fluxunits='flam')

    ################
    # Continuum, galaxy model
    templ = utils.load_templates(full_line_list=[],
                                 line_complexes=False,
                                 alf_template=True)['alf_SSP.dat']
    cont = S.ArraySpectrum(templ.wave * (1 + z), templ.flux, fluxunits='flam')

    # Gaussian line model
    ref_flux = 1.e-17
    line_model = S.GaussianSource(ref_flux,
                                  line_wave * (1 + z),
                                  10,
                                  waveunits='angstrom',
                                  fluxunits='flam')

    cont_contin_countrate = S.Observation(cont,
                                          bandpasses[cont_filter]).countrate()
    line_contin_countrate = S.Observation(cont,
                                          bandpasses[line_filter]).countrate()
    line_emline_countrate = S.Observation(line_model,
                                          bandpasses[line_filter]).countrate()

    # Continuum-subtracted, flux-calibrated
    line_calib = (
        images[line_filter][0] -
        images[cont_filter][0] * line_contin_countrate / cont_contin_countrate)
    line_calib /= line_emline_countrate

    # Propagated error of the subtraction
    err_sub = np.sqrt((images[line_filter][1]**2) +
                      (images[cont_filter][1] * line_contin_countrate /
                       cont_contin_countrate)**2)
    err_sub /= line_emline_countrate

    if plot:
        print("Continuum subtracted image")
        plt.figure()
        plt.imshow(line_calib, vmin=-0.5, vmax=0.5)
        plt.colorbar()

    primary_extn = pyfits.PrimaryHDU()
    sci_extn = pyfits.ImageHDU(data=line_calib, name='SCI')
    err_extn = pyfits.ImageHDU(data=err_sub, name='ERR')
    hdul = pyfits.HDUList([primary_extn, sci_extn, err_extn])
    hdul.writeto('sub_{0}_{1}.fits'.format(line_name, target),
                 output_verify='fix',
                 overwrite=True)

    print(line_name, ' Continuum Subtracted')
예제 #3
0
def photometry(filters_path,
               filters_list,
               specs_path,
               specs_list,
               telescope_area,
               results_path,
               confidence=0.6,
               plot=False,
               save=False):
    """

    :param filters_path: add the path to your filters response files -- e.g '/home/user/Documents/Filters'
    :param filters_list: add the path and name of your filters' list
    -- e.g '/home/user/Documents/filters_list.txt'
    Inside this list you should have all the filters' response files that you are going to use
    -- e.g.:
    uSDSS.txt
    gSDSS.txt
    rSDSS,txt
    iSDSS.txt
    zSDSS.txt
    You can create it in your command line by doing the following command:
    $ ls /home/user/Documents/Filters >> /home/user/Documents/filters_list.txt
    :param specs_path: add the path to your spectra files -- e.g '/home/user/Documents/Specs'
    :param specs_list: similar to the filters_list
    :param telescope_area: the default parameter is 4400 which is the J-PAS T80 M1 effective area in cm^2.
    Set it as you wish given your telescope.
    :param results_path: add the path where you would like to save your results. It is only obligatory if you set
    plot=True
    :param confidence: the confidence that you would like to add in order to calculate a simulated photometry.
    This is important for the photometry of the borders of the spectra. This will limit the calculation of the
    photometry in terms of the wavelength range. If the filter occupies less than X% of your spectrum wavelength range,
    it will generate an error value (-999), but if it occupies more than X% it will do the convolution the filter with
    the spectrum. The default value is 60% (0.6), but you can change this at your will.
    :param plot: if you want to plot the results and save them, please set 'plot=True'. If not, please set 'plot=False'.
    The default is false.
    :param save: if you want to save the results, please set 'save=True'. If not, please set 'save=False'.
    The default is False.
    is false.
    :return: The returned parameters are:
    1) photometry: your simulated photometry. This is your main result.
    2) lambda_eff: effective wavelengths of your filters.
    3) photometry_flam: the simulated photometry in terms of flux_lambda
    4) photometry_fnu: the simulated photometry in terms of flux_fnu
    5) filter_name: the name of the filters you used in each round. This is not very important, you can ignore this.
    """

    # Setting the telescope area; the default parameter is the T80 M1 effective area in cm^2 ---------------------------
    if telescope_area == None:
        s.setref(area=4400)
    else:
        s.setref(area=telescope_area)

    # Reading your files -----------------------------------------------------------------------------------------------
    filters_list = np.loadtxt(filters_list, dtype=str)
    specs_list = np.loadtxt(specs_list, dtype=str)

    # Simulating photometry for your spectra using the selected survey filters -----------------------------------------
    count = 0
    for each_spectrum in specs_list:
        print each_spectrum
        filter_name = []
        photometry = []
        photometry_flam = []
        lambda_eff = []
        for filters in filters_list:
            # saving an array with the filters names -------------------------------------------------------------------
            filter_name_i = filters.split('.')[0]
            filter_name.append(filter_name_i)

            # convolution ----------------------------------------------------------------------------------------------
            filter_bandpass = s.FileBandpass(
                os.path.join(filters_path, filters))
            spectrum = s.FileSpectrum(os.path.join(
                specs_path, each_spectrum))  # the entire spectrum
            index = np.where(
                spectrum.flux >
                0)  # selecting only the positive part of the spectrum
            spectrum2 = s.ArraySpectrum(wave=spectrum.wave[index],
                                        flux=spectrum.flux[index],
                                        fluxunits=spectrum.fluxunits,
                                        waveunits=spectrum.waveunits)
            binset = filter_bandpass.wave  # this is very very important! don't change this unless
            # you are absolutely sure of what you are doing!
            ## convolved photometry ------------------------------------------------------------------------------------
            photometry_i = s.Observation(spectrum2,
                                         filter_bandpass,
                                         binset=binset,
                                         force='extrap')

            ## effective wavelength ------------------------------------------------------------------------------------
            lambda_eff_i = photometry_i.efflam()
            lambda_eff.append(lambda_eff_i)

            ## checking if the simulated photometry is "virtual" and letting those away --------------------------------
            if filter_bandpass.wave.min() < spectrum2.wave.min():
                if filter_bandpass.wave.max() - spectrum2.wave.min(
                ) > confidence * (filter_bandpass.wave.max() -
                                  filter_bandpass.wave.min()):
                    photometry.append(photometry_i.effstim('abmag'))
                    photometry_flam_i = photometry_i.effstim('flam')
                    photometry_flam.append(photometry_flam_i)

                else:
                    new_photometry_i = -999
                    photometry.append(new_photometry_i)
                    photometry_flam.append(new_photometry_i)

            elif filter_bandpass.wave.max() > spectrum2.wave.max():
                if spectrum2.wave.max() - filter_bandpass.wave.min(
                ) > confidence * (filter_bandpass.wave.max() -
                                  filter_bandpass.wave.min()):
                    photometry.append(photometry_i.effstim('abmag'))
                    photometry_flam_i = photometry_i.effstim('flam')
                    photometry_flam.append(photometry_flam_i)

                else:
                    new_photometry_i = -999
                    photometry.append(new_photometry_i)
                    photometry_flam.append(new_photometry_i)

            else:
                photometry.append(photometry_i.effstim('abmag'))
                photometry_flam_i = photometry_i.effstim('flam')
                photometry_flam.append(photometry_flam_i)

        count = count + 1

        # putting the iterated items into arrays -----------------------------------------------------------------------
        filter_name = np.array(filter_name)  # name of each filter
        photometry = np.array(photometry)  # in magnitudes
        lambda_eff = np.array(
            lambda_eff)  # effective wavelengths of the filters
        photometry_flam = np.array(photometry_flam)  # in flux of lambda
        photometry_fnu = 10**(-0.4 * (photometry + 48.60))  # in flux of nu

        if (plot == False) * (save == False):
            continue

        elif (plot == False) * (save == True):
            # saving the newley calculated photometry ------------------------------------------------------------------
            galaxy_simulation_abmag = np.vstack((filter_name, photometry))
            galaxy_simulation_abmag = pd.DataFrame(galaxy_simulation_abmag)
            galaxy_simulation_abmag.to_csv(os.path.join(
                results_path,
                str(count) + '_abmag.csv'),
                                           sep=',',
                                           header=None,
                                           index=False)
            galaxy_simulation_fnu = np.vstack((filter_name, photometry_fnu))
            galaxy_simulation_fnu = pd.DataFrame(galaxy_simulation_fnu)
            galaxy_simulation_fnu.to_csv(os.path.join(results_path,
                                                      str(count) + '_fnu.csv'),
                                         sep=',',
                                         header=None,
                                         index=False)

        elif (plot == True) * (save == False):
            # plots ----------------------------------------------------------------------------------------------------
            plt.plot(spectrum2.wave, spectrum2.flux, '-')
            plt.plot(lambda_eff[[photometry_flam != -999]],
                     photometry_flam[[photometry_flam != -999]], 'o')
            plt.title(r"%s" % each_spectrum, size='15')
            plt.savefig(os.path.join(results_path,
                                     'object_' + str(count) + '.png'),
                        dpi=100)
            plt.show()

        elif (plot == True) * (save == True):
            # plots ----------------------------------------------------------------------------------------------------
            plt.plot(spectrum2.wave, spectrum2.flux, '-')
            plt.plot(lambda_eff[[photometry_flam != -999]],
                     photometry_flam[[photometry_flam != -999]], 'o')
            plt.title(r"%s" % each_spectrum, size='15')
            plt.savefig(os.path.join(results_path,
                                     'object_' + str(count) + '.png'),
                        dpi=100)
            plt.show()

            # saving the newley calculated photometry ------------------------------------------------------------------
            galaxy_simulation_abmag = np.vstack((filter_name, photometry))
            galaxy_simulation_abmag = pd.DataFrame(galaxy_simulation_abmag)
            galaxy_simulation_abmag.to_csv(os.path.join(
                results_path, 'object_' + str(count) + '_abmag.csv'),
                                           sep=',',
                                           header=None,
                                           index=False)
            galaxy_simulation_fnu = np.vstack((filter_name, photometry_fnu))
            galaxy_simulation_fnu = pd.DataFrame(galaxy_simulation_fnu)
            galaxy_simulation_fnu.to_csv(os.path.join(
                results_path, 'object_' + str(count) + '_fnu.csv'),
                                         sep=',',
                                         header=None,
                                         index=False)

    return photometry, lambda_eff, photometry_flam, photometry_fnu, filter_name
예제 #4
0
    distance = distance * 100  #cm

    #expected flux per cm^2 at 1kpc
    F = L / (4 * math.pi * (distance**2))  #erg/s/cm^2 /ster?
    #Expected flux per sq cm of a CS  at the distance
    print 'Flux at ', distance_parsec, 'pc: ', F, 'erg/s/cm^2'

    #calcualte multiplication factor needed to convert the input spectum to one of an object at 1kpc
    m_factor = F / total_flux
    new_flux = [line['F_lambda'] * m_factor for line in spectrum]  #erg/s/cm^2

    #multiply by the star's surface area to get erg/s
    new_flux = [line * SA for line in new_flux]

    #redden the array using CCM1998, Rv=3.1
    spectrum = S.ArraySpectrum(np.array(wl), np.array(new_flux), 'angstrom',
                               'flam')
    spectrum = spectrum * S.Extinction(EBmV, 'mwavg')

    #calculate colours
    obs_u = S.Observation(spectrum, u_bp)
    obs_g = S.Observation(spectrum, g_bp)
    obs_r = S.Observation(spectrum, r_bp)
    obs_i = S.Observation(spectrum, i_bp)

    u_mag = obs_u.effstim(magsystem)
    g_mag = obs_g.effstim(magsystem)
    r_mag = obs_r.effstim(magsystem)
    i_mag = obs_i.effstim(magsystem)

    u_min_g = obs_u.effstim(magsystem) - obs_g.effstim(magsystem)
    g_min_r = obs_g.effstim(magsystem) - obs_r.effstim(magsystem)
예제 #5
0
 def setUp(self):
     self.sp = S.ArraySpectrum(N.arange(3000, 6000, 500),
                               N.array([1.0, 0.5, 0.2, 0.1, -0.1, -0.3]) *
                               1e-14,
                               fluxunits='flam')
예제 #6
0
tubigen_path = '/mirror2/scratch/hbarker/Macquarie/CS_synthetic_colours/TubingenModels'
spectrum_fpath = glob.glob(tubigen_path + '/100kK_7.0_solar/*.txt')
spectrum_fpath = spectrum_fpath[0]

wl = []
flx = []
with open(spectrum_fpath, 'r') as f:
	for line in f:
		line = line.split()
		#[Angstrom, eg/s/cm2/cm]	
		wl.append( float(line[0]) )
		flx.append( float(line[1])*1e-8  ) #convert to per angstrom
print 'Spectrum read in'		
		
#create pysynphot spectrum
spectrum = S.ArraySpectrum(np.array(wl), np.array(flx), 'angstrom', 'flam')		

synth_colours = []

#use pysynphot to redden the spectrum 
#redden the spectrum  using Cardelli 1989, RV=3.1
E_BmV = [0.0, 0.4, 0.6, 0.8, 1.0, 1.3, 1.5, 2.0]
for e in E_BmV:

	print 'E(B-V):', e
	red_spectrum = spectrum *  S.Extinction(e, 'mwavg')
	
	#plt.figure()
	#plt.plot(red_spectrum.wave, red_spectrum.flux)
	#plt.xlabel(red_spectrum.waveunits)
	#plt.ylabel(red_spectrum.fluxunits)
예제 #7
0
def pre_process_source(source,
                       sourcemag,
                       sourcepb,
                       sourcez,
                       smooth=True,
                       Renorm=True,
                       svo=False):
    """
    Pre-process a source at some redshift ``sourcez`` back to the rest-frame
    and normalize it to have magnitude ``sourcemag`` in passband ``sourcepb``

    Parameters
    ----------
    sourcespec : str
            The source spectrum filename
    sourcemag : float
            The magnitude of the source spectrum in passband ``sourcepb``
    sourcepb : :py:class:`pysynphot.spectrum.ArraySpectralElement`
            The passband in which `source` has magnitude ``sourcemag``
    sourcez : float
            The redshift of `source`
    smooth : bool, optional
            Smooth the spectrum (default: True)

    Returns
    -------
    source : :py:class:`pysynphot.ArraySpectrum`
        The de-redshifted, normalized and optionally smoothed spectrum

    See Also
    --------
    :py:func:`astropy.table.Table.read`
    """
    inspec = None
    inspecz = np.nan
    inspecmag = np.nan
    inspecpb = None

    source_table_file = os.path.join('sources', 'sourcetable.txt')
    source_table_file = io.get_pkgfile(source_table_file)
    source_table = at.Table.read(source_table_file, format='ascii')
    ind = (source_table['specname'] == source)
    nmatch = len(source_table['specname'][ind])

    if nmatch == 1:
        # load the file and the info
        inspec = os.path.join('./source_synphot/sources',
                              source_table['specname'][ind][0])
        inspecz = source_table['redshift'][ind][0]
        inspecmag = source_table['g'][ind][
            0]  # for now, just normalize the g-band mag
        inspecpb = sourcepb
    elif nmatch == 0:
        message = 'Spectrum {} not listed in lookup table'.format(source)
        pass
    else:
        message = 'Spectrum {} not uniquely listed in lookup table'.format(
            source)
        pass

    if inspec is None:
        warnings.warn(message, RuntimeWarning)
        inspec = source
        inspecz = sourcez
        inspecmag = sourcemag
        inspecpb = sourcepb
    if svo:
        inspecpb, _ = io.SVO_passband(sourcepb)
    #sourcemag = np.nan
    if sourcemag is None:
        #if np.isnan(inspecmag):
        #    sourcemag = inspecmag
        #else:
        sourcemag = float(inspecmag)

    if not os.path.exists(inspec):
        message = 'Spectrum {} could not be found'.format(inspec)
        raise ValueError(message)

    try:
        spec = at.Table.read(inspec, format='ascii')
    except Exception as e:
        message = 'Could not read file {}'.format(source)
        raise ValueError(message)

    if hasattr(inspecpb, 'wave') and hasattr(inspecpb, 'throughput'):
        pass
    else:

        pbs = passband.load_pbs([inspecpb], 0.)
        try:
            inspecpb = pbs[inspecpb][0]
        except KeyError as e:
            message = 'Could not load passband {}'.format(inspecpb)
            raise RuntimeError(message)

    try:
        inspecmag = float(inspecmag)
    except (TypeError, ValueError) as e:
        message = 'Source magnitude {} could not be interpreted as a float'.format(
            inspecmag)
        raise ValueError(message)

    try:
        inspecz = float(inspecz)
    except (TypeError, ValueError) as e:
        message = 'Source redshift  {} could not be interpreted as a float'.format(
            inspecz)
        raise ValueError(message)

    if inspecz < 0:
        message = 'Source must have positive definite cosmological redshift'
        raise ValueError(message)

    inspec = S.ArraySpectrum(spec['wave'], spec['flux'], fluxunits='flam')

    if Renorm:
        try:
            #print('sourcemag',sourcemag)
            inspec = inspec.renorm(sourcemag, 'ABmag', inspecpb)
            inspec.convert('flam')
        except Exception as e:
            message = 'Could not renormalize spectrum {}'.format(inspec)
            raise RuntimeError(message)

    if inspecz > 0:
        zblue = 1. / (1 + inspecz) - 1.
        inspec_rest = inspec.redshift(zblue)
        inspec_rest.convert('flam')
        c = default_cosmology.get()
        mu = c.distmod(inspecz)
        out = inspec_rest * (10.**(0.4 * mu.value))
    else:
        out = inspec
    # TODO renorm is basic and just calculates dmag = RNval - what the original spectrum's mag is
    # and renormalizes - there's some sanity checking for overlaps
    # we can do this without using it and relying on the .passband routines
    return out
				F_MS = MS_expected_lum / (4*math.pi*(distance_cm**2)) #expected flux of the star at the distance
				ms_factor = F_MS/MS_total_flux
				MS = [val*ms_factor for val in MS]

				F_CS = CS_expected_lum / (4*math.pi*(distance_cm**2))
				cs_factor = F_CS/CS_total_flux
				CS = [val*cs_factor for val in CS]


				#sum the flux of the CS and MS stars		
				spectra_sum = [line[0]+line[1] for line in zip(CS, MS)]


				#convolve with the vphas bands
				spectrum=S.ArraySpectrum(np.array(wavelengths_AA), np.array(spectra_sum), waveunits='angstrom', fluxunits='flam')
	
	
				#redden the spectrum
				spectrum = spectrum * S.Extinction(reddening, 'mwavg')	
	
	
	
				#calculate magnitudes and colours using pysynphot
				obs_u = S.Observation(spectrum, u_bp)
				obs_g = S.Observation(spectrum, g_bp)
				obs_r = S.Observation(spectrum, r_bp)
				obs_i = S.Observation(spectrum, i_bp)
				#obs_V = S.Observation(spectrum, S.ObsBandpass('V'))
				#obs_B = S.Observation(spectrum, S.ObsBandpass('B'))
				#obs_R = S.Observation(spectrum, S.ObsBandpass('R'))
예제 #9
0
    def __init__(self,
                 galaxy_id,
                 redshift,
                 metal,
                 age,
                 tau,
                 minwv=7900,
                 maxwv=11300,
                 pad=100,
                 delayed_tau=True):
        import pysynphot as S
        self.galaxy_id = galaxy_id
        self.redshift = redshift
        self.metal = metal
        self.age = age
        self.tau = tau
        self.pad = pad
        self.delayed_tau = delayed_tau
        """ 
        self.flt_input - grism flt (not image flt) which contains the object you're interested in modeling, this
                         will tell Grizli the PA
        **
        self.galaxy_id - used to id galaxy and import spectra
        **
        self.pad - Grizli uses this to add extra pixels to the edge of an image to account for galaxies near the 
                   edge, 100 is usually enough
        **
        self.beam - information used to make models
        **
        self.gal_wv - output wavelength array of galaxy
        **
        self.gal_wv_rf - output wavelength array in restframe
        **
        self.gal_fl - output flux array of galaxy
        **
        self.gal_er - output error array of galaxy
        **
        self.fl - output flux array of model used for simulation
        **
        self.flx_err - output flux array of model perturb by the galaxy's 1 sigma errors
        **
        self.mfl - output flux array of model generated to fit against 
        """

        gal_wv, gal_fl, gal_er = \
            np.load('../../../../fdata/scratch/vestrada78840/spec_stacks_june14/%s_stack.npy' % self.galaxy_id)
        self.flt_input = '../../../../fdata/scratch/vestrada78840/galaxy_flts/%s_flt.fits' % self.galaxy_id

        IDX = [U for U in range(len(gal_wv)) if minwv <= gal_wv[U] <= maxwv]

        self.gal_wv_rf = gal_wv[IDX] / (1 + self.redshift)
        self.gal_wv = gal_wv[IDX]
        self.gal_fl = gal_fl[IDX]
        self.gal_er = gal_er[IDX]

        self.gal_wv_rf = self.gal_wv_rf[self.gal_fl > 0]
        self.gal_wv = self.gal_wv[self.gal_fl > 0]
        self.gal_er = self.gal_er[self.gal_fl > 0]
        self.gal_fl = self.gal_fl[self.gal_fl > 0]

        ## Create Grizli model object
        sim_g102 = grizli.model.GrismFLT(grism_file='',
                                         verbose=False,
                                         direct_file=self.flt_input,
                                         force_grism='G102',
                                         pad=self.pad)

        sim_g102.photutils_detection(detect_thresh=.025,
                                     verbose=True,
                                     save_detection=True)

        keep = sim_g102.catalog['mag'] < 29
        c = sim_g102.catalog

        sim_g102.compute_full_model(ids=c['id'][keep],
                                    mags=c['mag'][keep],
                                    verbose=False)

        ## Grab object near the center of the image
        dr = np.sqrt((sim_g102.catalog['x_flt'] - 579)**2 +
                     (sim_g102.catalog['y_flt'] - 522)**2)
        ix = np.argmin(dr)
        id = sim_g102.catalog['id'][ix]

        ## Spectrum cutouts
        self.beam = grizli.model.BeamCutout(
            sim_g102,
            beam=sim_g102.object_dispersers[id]['A'],
            conf=sim_g102.conf)

        ## create basis model for sim

        if self.delayed_tau == False:
            model = '../../../../fdata/scratch/vestrada78840/fsps_spec/m%s_a%s_t%s_spec.npy' % (
                self.metal, self.age, self.tau)
        else:
            model = '../../../../fdata/scratch/vestrada78840/fsps_spec/m%s_a%s_dt%s_spec.npy' % (
                self.metal, self.age, self.tau)

        wave, fl = np.load(model)
        spec = S.ArraySpectrum(wave, fl, fluxunits='flam')
        spec = spec.redshift(self.redshift).renorm(
            1., 'flam', S.ObsBandpass('wfc3,ir,f105w'))
        spec.convert('flam')
        ## Compute the models
        self.beam.compute_model(spectrum_1d=[spec.wave, spec.flux])

        ## Extractions the model (error array here is meaningless)
        w, f, e = self.beam.beam.optimal_extract(self.beam.model, bin=0)

        ifl = interp1d(w, f)(self.gal_wv)

        ## Get sensitivity function
        fwv, ffl = [
            self.beam.beam.lam,
            self.beam.beam.sensitivity / np.max(self.beam.beam.sensitivity)
        ]
        filt = interp1d(fwv, ffl)(self.gal_wv)

        adj_ifl = ifl / filt

        C = Scale_model(self.gal_fl, self.gal_er, adj_ifl)

        self.fl = C * adj_ifl

        m2r = [
            3175, 3280, 3340, 3515, 3550, 3650, 3710, 3770, 3800, 3850, 3910,
            4030, 4080, 4125, 4250, 4385, 4515, 4570, 4810, 4910, 4975, 5055,
            5110, 5285
        ]

        Mask = np.zeros(len(self.gal_wv_rf))
        for i in range(len(Mask)):
            if m2r[0] <= self.gal_wv_rf[i] <= m2r[1]:
                Mask[i] = 1
            if m2r[2] <= self.gal_wv_rf[i] <= m2r[3]:
                Mask[i] = 1
            if m2r[4] <= self.gal_wv_rf[i] <= m2r[5]:
                Mask[i] = 1
            if m2r[6] <= self.gal_wv_rf[i] <= m2r[7]:
                Mask[i] = 1
            if m2r[8] <= self.gal_wv_rf[i] <= m2r[9]:
                Mask[i] = 1
            if m2r[8] <= self.gal_wv_rf[i] <= m2r[9]:
                Mask[i] = 1
            if m2r[10] < self.gal_wv_rf[i] <= m2r[11]:
                Mask[i] = 1
            if m2r[12] <= self.gal_wv_rf[i] <= m2r[13]:
                Mask[i] = 1
            if m2r[14] <= self.gal_wv_rf[i] <= m2r[15]:
                Mask[i] = 1
            if m2r[16] <= self.gal_wv_rf[i] <= m2r[17]:
                Mask[i] = 1
            if m2r[18] <= self.gal_wv_rf[i] <= m2r[19]:
                Mask[i] = 1
            if m2r[20] <= self.gal_wv_rf[i] <= m2r[21]:
                Mask[i] = 1
            if m2r[22] <= self.gal_wv_rf[i] <= m2r[23]:
                Mask[i] = 1

        self.maskw = np.ma.masked_array(self.gal_wv_rf, Mask)

        params = np.ma.polyfit(self.maskw, self.fl, 3, w=1 / self.gal_er**2)
        C0 = np.polyval(params, self.gal_wv_rf)

        self.nc_fl = self.fl / C0
        self.nc_er = self.gal_er / C0
예제 #10
0
    def emission(self,sky_mag,sky_filter_name, wavelength=None):
        '''Return the dark sky emission spectrum, scaled to give integrated surface brightness
        `sky_mag` in filter `sky_filter_name`. 'sky_mag' is in mag/arcsec2.

        the CAHA dark sky spectrum is scaled to the sky_mag in the 
        user selected filter

        Per definition, the zeropoint of an AB mag spectrum is 48.6 in all filters.

        the sky flux F inside of a filter with transmission T (photon-counting transmission curve) is:
        integral(wavelength * T * F) / integral (wavelength * T)

        airmass is not taken into consideration, because there's no moon flux or distance to moon. 


        Parameters
        ----------

        sky_mag : float 
            the magnitude (per arcsec2) of the sky. Dark sky spectrum
            will be scaled to match this magnitude in the provided filter

        sky_filter_name : str 
            the name of the filter in which the sky magnitude is given. 
            must exist in pysynphot. For now, must be one of 
            'johnson,b'
            'johnson,v'
            'cousins,r'
            'cousins,i'

        wavelength : astropy.units.Quantity
            Optional wavelength array. If given, the transmission is rebinned
            to this wavelength array, otherwise the unbinned data is returned.

        Returns
        -------
        pysynphot.ArraySpectrum
            Arrayspectrum with flam as a function of wavelengths
        '''

        import pysynphot as S
        import astropy.constants as const
        
        
        FILTER = S.ObsBandpass(sky_filter_name)
        self.pivot_wave = FILTER.pivot()
        
        dark_flux = self.dark_sky_flux * u.arcsec**2
        
        spec = S.ArraySpectrum(self.wavelength, self.dark_sky_flux,waveunits='angstrom',fluxunits='flam')
        
        obs = S.Observation(spec,FILTER,binset=self.wavelength,force='taper')

        integrated_sky_flux_in_filter = obs.effstim('flam')
        desired_sky_flux_in_filter  = 10**(-0.4*(sky_mag+48.6)) * const.c.to('AA/s').value / FILTER.pivot()**2
        
        scaling_constant = desired_sky_flux_in_filter / integrated_sky_flux_in_filter
        
        print('Multiplying dark sky flux by %.3f'%scaling_constant)
        
        if wavelength is None:
            return S.ArraySpectrum(self.wavelength,self.dark_sky_flux* scaling_constant,waveunits='angstrom',fluxunits='flam') 
        else:
            rebin_flux = rebin_1d_flux_box(spec.flux,spec.wave,wavelength)
            return S.ArraySpectrum(wavelength,rebin_flux,waveunits=wavelength.unit,fluxunits='flam')
예제 #11
0
def calc_reddened_colours(temp):

	magsystem = 'vegamag'

	#read in transmission tables describing the VPHAS+ filter curves
	fpaths= glob.glob('/mirror2/scratch/hbarker/Macquarie/CS_synthetic_colours/vphas_atmosphere_included_filters/*.dat')
	for fpath in fpaths:
		bandpass = S.FileBandpass(fpath)
		with open(fpath, 'r') as f:
			tab = [line.strip().split() for line in f]
		#if 'u_SDSS' in fpath:
		#	u_bp = bandpass
		#elif 'g_SDSS' in fpath:
		#	g_bp = bandpass
		
		#use the filtercurved emailed by Janet Drew that contain the known u
		# and g band red leak
		if 'u-transmission' in fpath:
			bandpass = S.FileBandpass(fpath)
			u_bp = bandpass	
		elif 'g-transmission' in fpath:
			bandpass = S.FileBandpass(fpath)
			g_bp = bandpass	
		
		
		elif 'r_SDSS' in fpath:
			r_bp = bandpass
		elif 'i_SDSS' in fpath:
			i_bp = bandpass


	#read in PN model spectra from the TMAP models
	tmap_paths = glob.glob('/mirror2/scratch/hbarker/Macquarie/CS_synthetic_colours/TubingenModels/'+str(temp)+'kK_7.0_solar/*.txt')
	if len(tmap_paths)==0:
		print 'File does not exist'
		print '/mirror2/scratch/hbarker/Macquarie/CS_synthetic_colours/TubingenModels/'+str(temp)+'kK_7.0_solar/*.txt'
		sys.exit()
	fpath = tmap_paths[0]

	#read the spectrum into a table
	colnames = ['lambda', 'F_lambda']
	wl = []
	flx = []
	with open(fpath, 'r') as f:
		for line in f:
			line = line.split()
			wl.append(float(line[0])) #A
			#convert flux from erg/cm**2/s/cm to erg/s/cm**2/A
			flx_cgs = float(line[1])*1e-8
			flx.append(flx_cgs)
	
	#E(B-V) values to calculate		
	reddenings = np.arange(0,31, 1) #0, 0.1, 0.2, ...., 2.9, 3.0
	reddenings = [round(line/10.,3) for line in reddenings]
	
	EBmV_dict = {} # { 0.0 : [u-g, g-r, r-i], ... }
	for EBmV in reddenings:
		
		#construct spectrum for pysynphot
		spectrum = S.ArraySpectrum(np.array(wl), np.array(flx), 'angstrom', 'flam')
		
		
		#convert from flam to photons, as colours need to be calculatated in photon counts
		spectrum.convert('counts')	
		

		
		#redden the spectrum using cardelli1989 and Rv=3.1
		spectrum = spectrum * S.Extinction(EBmV, 'mwavg')
		
		obs_u = S.Observation(spectrum, u_bp)
		obs_g = S.Observation(spectrum, g_bp)
		obs_r = S.Observation(spectrum, r_bp)
		obs_i = S.Observation(spectrum, i_bp)

		#calculate colours
		u_min_g = obs_u.effstim(magsystem) - obs_g.effstim(magsystem)
		g_min_r = obs_g.effstim(magsystem) - obs_r.effstim(magsystem)
		r_min_i = obs_r.effstim(magsystem) - obs_i.effstim(magsystem)

		#Add EBmV and colours to the dictionary
		colours = [u_min_g, g_min_r, r_min_i]
		EBmV_dict[ EBmV ] = colours
		
	return EBmV_dict
예제 #12
0
import pysynphot as S
import astropy.table as at
import webbpsf as W
nc = W.NIRCam()
nc.filter = 'F115W'
bp = nc._getSynphotBandpass(nc.filter)
f = at.Table.read('Tables/kilnova_orig_50Mpc_p+5.25.txt', format='ascii')
spec = S.ArraySpectrum(f['wave_micron'],
                       f['flux_mjy'],
                       waveunits='micron',
                       fluxunits='ujy')
spec2 = S.ArraySpectrum(f['wave_micron'],
                        f['flux_mjy'] * 1E8,
                        waveunits='micron',
                        fluxunits='ujy')
TELESCOPE_AREA = 25.0 * 10000
S.setref(area=TELESCOPE_AREA)
obs = S.Observation(spec, bp, force='taper')
obs2 = S.Observation(spec2, bp, force='taper')
print('WRONG FOR PYSYNPHOT, RIGHT FOR ETC:', obs.effstim('abmag'))
print('RIGHT FOR PYSYNPHOT, WRONG FOR ETC:', obs2.effstim('abmag'))
예제 #13
0
def mags(age=None, mag435=None, plot=False):
    # uses the starburst99 spectrum, convolves with pre-defined filters to get the
    # color difference between F435W filter and others. Returns magnitudes in other
    # filters given the F435W magnitude.

    inspec = Spec(age=age)
    sp = S.ArraySpectrum(wave=inspec.wave,
                         flux=inspec.mag,
                         waveunits='angstrom',
                         fluxunits='stmag')

    # get the NIRC2 filters (HST filters are pre-defined)
    filtJ = nirc2syn.FilterNIRC2('J')
    filtH = nirc2syn.FilterNIRC2('H')
    filtK = nirc2syn.FilterNIRC2('Kp')

    # ACS
    obs330 = S.Observation(sp, S.ObsBandpass('acs,hrc,f330w'))
    obs435 = S.Observation(sp, S.ObsBandpass('acs,hrc,f435w'))
    # WFPC2
    obs555 = S.Observation(sp, S.ObsBandpass('wfpc2,1,f555w,a2d7,cont#49888'))
    obs814 = S.Observation(sp, S.ObsBandpass('wfpc2,1,f814w,a2d7,cont#49888'))
    obs1024 = S.Observation(sp,
                            S.ObsBandpass('wfpc2,1,f1042M,a2d7,cont#49628'))
    # NIRC2
    obs1249 = S.Observation(sp, filtJ, binset=filtJ.wave)
    obs1633 = S.Observation(sp, filtH, binset=filtH.wave)
    obs2125 = S.Observation(sp, filtK, binset=filtK.wave)

    intmag = np.zeros(8, dtype=float)
    intmag[0] = obs330.effstim('stmag')
    intmag[1] = obs435.effstim('stmag')
    intmag[2] = obs555.effstim('stmag')
    intmag[3] = obs814.effstim('stmag')
    intmag[4] = obs1024.effstim('stmag')
    intmag[5] = obs1249.effstim('stmag')
    intmag[6] = obs1633.effstim('stmag')
    intmag[7] = obs2125.effstim('stmag')

    colors = np.zeros(8, dtype=float)
    calmag = np.zeros(8, dtype=float)
    # F435W - X
    for i in range(len(colors)):
        tmp = intmag[1] - intmag[i]
        colors[i] = tmp
        tmpmag = mag435 - tmp
        calmag[i] = tmpmag

    print('Filter: F435W-X color, mag')
    print('F330W: %5.2f, %5.2f' % (colors[0], calmag[0]))
    print('F435W: %5.2f, %5.2f' % (colors[1], calmag[1]))
    print('F555W: %5.2f, %5.2f' % (colors[2], calmag[2]))
    print('F814W: %5.2f, %5.2f' % (colors[3], calmag[3]))
    print('F1042M: %5.2f, %5.2f' % (colors[4], calmag[4]))
    print('J: %5.2f, %5.2f' % (colors[5], calmag[5]))
    print('H: %5.2f, %5.2f' % (colors[6], calmag[6]))
    print('Kp: %5.2f, %5.2f' % (colors[7], calmag[7]))

    magdiff = intmag[1] - mag435
    plfilt = [3300., 4350., 5550., 8140., 10420., 12490., 16330., 21250.]

    if plot:
        py.figure(2)
        py.clf()
        py.plot(inspec.wave, inspec.mag - magdiff)
        py.xlim(3000, 22000)
        for i in range(len(plfilt)):
            py.plot([plfilt[i], plfilt[i]], [13, 18], 'k--')
        py.ylim(18, 13)
        py.xlabel('Wavelength (angstrom)')
        py.ylabel('Mag')
        pltitle = 'P3 (5000 M$_{\odot}$, %4.1f Myr)' % (age / 1.e6)
        py.title(pltitle)
예제 #14
0
def outTrans(input) :
    """Compute out of transit spectra
    
    Computes the out of transit spectra by normalizing flux to specified 
    magnitude and convert to specified Pandeia units of milliJy and microns.  
  
    Parameters 
    ----------
    input : dict
        stellar scene which includes parameters to extract phoenix database or a 
        filename which points to a stellar spectrum 
    
    Return
    ------
    dict 
        contains wave and flux_out_trans
    """ 

    ref_wave = float(input['ref_wave'])
    mag = float(input['mag'])

    ################# USER ####################################
    if input['type'] == 'user':
        if isinstance(input['starpath'], dict):
            star = input['starpath']
        else: #if isinstance(input['starpath'], str):
            star = np.genfromtxt(input['starpath'], dtype=(float, float),
                                 names='w, f')
        #get flux 
        flux = star['f'] #star.field(input['logg'])
        #get wavelength and reference wavelength for mag normalization
        wave = star['w'] #star.field('WAVELENGTH')
        
        #sort if not in ascending order 
        sort = np.array([wave,flux]).T
        sort= sort[sort[:,0].argsort()]
        wave = sort[:,0]
        flux = sort[:,1] 
        if input['w_unit'] == 'um':
            PANDEIA_WAVEUNITS = 'um'
            
        elif input['w_unit'] == 'nm':
            PANDEIA_WAVEUNITS = 'nm'
      
        elif input['w_unit'] == 'cm' :
            PANDEIA_WAVEUNITS = 'cm'
     
        elif input['w_unit'] == 'Angs' :
            PANDEIA_WAVEUNITS = 'angstrom'

        elif input['w_unit'] == 'Hz' :
            PANDEIA_WAVEUNITS = 'Hz'

        else: 
            raise Exception('Units are not correct. Pick um, nm, cm, hz, or Angs')        

        #convert to photons/s/nm/m^2 for flux normalization based on 
        #http://www.gemini.edu/sciops/instruments/integration-time-calculators/itc-help/source-definition
        if input['f_unit'] == 'Jy':
            PANDEIA_FLUXUNITS = 'jy' 
        elif input['f_unit'] == 'FLAM' :
            PANDEIA_FLUXUNITS = 'FLAM'
        elif input['f_unit'] == 'erg/cm2/s/Hz':
            flux = flux*1e23
            PANDEIA_FLUXUNITS = 'jy' 
        else: 
            raise Exception('Units are not correct. Pick FLAM or Jy or erg/cm2/s/Hz')

        sp = psyn.ArraySpectrum(wave, flux, waveunits=PANDEIA_WAVEUNITS, fluxunits=PANDEIA_FLUXUNITS)        #Convert evrything to nanometer for converstion based on gemini.edu  
        sp.convert("nm")
        sp.convert('jy')

    ############ PHOENIX ################################################
    elif input['type'] =='phoenix':
        #make sure metal is not out of bounds
        if input['metal'] > 0.5: input['metal'] = 0.5
        sp = psyn.Icat("phoenix", input['temp'], input['metal'], input['logg'])
        sp.convert("nm")
        sp.convert("jy")
        wave = sp.wave
        flux = sp.flux
        input['w_unit'] ='nm'
        input['f_unit'] = 'jy'
        
    else: 
        raise Exception('Wrong input type for stellar spectra')
    

    ############ NORMALIZATION ################################################
    refdata = os.environ.get("pandeia_refdata")

    all_bps = {"H": 'bessell_h_004_syn.fits',
                 "J":'bessell_j_003_syn.fits' ,
                 "K": 'bessell_k_003_syn.fits'}

    if (ref_wave <= 1.3) & (ref_wave >= 1.2):
        filt = 'J'
    elif (ref_wave <= 1.7) & (ref_wave >= 1.6):
        filt = 'H'
    elif (ref_wave <= 2.3) & (ref_wave >= 2.1):
        filt = 'K'
    else:
        raise Exception('Only J H and K zeropoints are included')

    bp_path = os.path.join(refdata, "normalization", "bandpass", all_bps[filt])
    bp = psyn.FileBandpass(bp_path)

    sp.convert('angstroms')
    bp.convert('angstroms')

    rn_sp = sp.renorm(mag, 'vegamag', bp)


    rn_sp.convert("microns")
    rn_sp.convert("mjy")

    flux_out_trans = rn_sp.flux
    wave = rn_sp.wave
    return {'flux_out_trans': flux_out_trans, 'wave': wave,'phoenix':sp} 
예제 #15
0
 def use(self):
     spec = pys.ArraySpectrum(wave=self._wave,
                              flux=self._flux,
                              waveunits=self._wunit,
                              fluxunits=self._funit)
     return spec
예제 #16
0
table = []

#calculate Alambda values at a range of E(B-V)
for e, a in zip(E_BmV, Av):

    scaled_alambda = [val * a for val in cut_alambda]

    #calculate reddened flux
    #f_obs = f_intrinsiic * 10^ (-Alambda/2.5)
    reddened_flx = [
        line[0] * (10**((-line[1]) / 2.5))
        for line in zip(cut_flx, scaled_alambda)
    ]

    #make this into a spectrum and convolve with the vphas bands
    reddened_cs = S.ArraySpectrum(np.array(cut_wl), np.array(reddened_flx),
                                  'angstrom', 'flam')

    #convert from flam to photons, as colours need to be calculatated in photon counts
    reddened_cs.convert('counts')

    #plt.figure()
    #plt.plot(cut_wl, reddened_flx, 'r')
    #plt.plot(cut_wl, cut_flx, 'k')
    #plt.plot(u_bp.wave, u_bp.throughput, 'k--')
    #plt.show()

    #calcuate colours
    obs_u = S.Observation(reddened_cs, u_bp, force='extrap')
    obs_g = S.Observation(reddened_cs, g_bp)
    obs_r = S.Observation(reddened_cs, r_bp)
    obs_i = S.Observation(reddened_cs, i_bp)
예제 #17
0
def generate_single_kcorrection_listing(
        log,
        pathToOutputDirectory,
        pathToSpectralDatabase,
        model,
        restFrameFilter,
        redshift,
        temporalResolution=4.0):
    """
    *Given a redshift generate a dictionary of k-correction polynomials for the MCS.*

    **Key Arguments:**
        - ``log`` -- logger
        - ``pathToOutputDirectory`` -- path to the output directory (provided by the user)
        - ``pathToSpectralDatabase`` -- path to the directory containing the spectral database
        - ``model`` -- name of the object/model required
        - ``restFrameFilter`` -- the filter to generate the K-corrections against
        - ``redshift`` -- the redshift at which to generate the k-corrections for
        - ``temporalResolution`` -- temporal resolution at which to calculate the k-correcions

    **Return:**
        - None
    """
    ################ > IMPORTS ################
    ## STANDARD LIB ##
    import re
    import os
    import glob

    ## THIRD PARTY ##
    import yaml
    import pysynphot as syn
    ## LOCAL APPLICATION ##

    ################ >ACTION(S) ################
    # GET THE PEAK MAGNITUDE DETAILS FROM YAML FILE
    fileName = pathToOutputDirectory + "transient_light_curves.yaml"
    stream = file(fileName, 'r')
    generatedLCs = yaml.load(stream)
    filterData = generatedLCs[model]
    peakMag = generatedLCs[model][restFrameFilter]['Peak Magnitude']
    peakTime = generatedLCs[model][restFrameFilter]['Peak Time in Spectra']
    stream.close()

    pwd = os.getcwd()
    path = pathToSpectralDatabase + "/" + model + "/"

    title = "%s Objects" % (model,)
    os.chdir(path)
    spectrumFiles = []
    for thisFile in glob.glob("*.spec"):

        thisFile = path + thisFile
        spectrumFiles.append(thisFile)

    os.chdir(pwd)

    ################ > VARIABLE SETTINGS ######
    reTime = re.compile(r't((\+|\-)\d{3}\.\d{2})')

    ################ >ACTION(S) ################
    # CREATE THE REQUIRED DIRECTORIES
    filters = ["g", "i", "r", "z"]
    for thisFilter in filters:
        strRed = "%0.2f" % (redshift,)
        try:
            log.debug("attempting to create directories")
            dataDir = pathToOutputDirectory + \
                "k_corrections/%s/%s" % (model, thisFilter)
            os.makedirs(dataDir)
        except Exception as e:
            log.debug(
                "could not create directories - failed with this error: %s " % (str(e),))

        try:
            log.debug("attempting to clear the k-correction yaml file")
            fileName = dataDir + "/z" + \
                str(strRed).replace(".", "pt") + ".yaml"
            stream = file(fileName, 'w')
            stream.close()
        except Exception as e:
            log.critical(
                "could not clear the k-correction yaml file - failed with this error: %s " % (str(e),))
            return -1

    timesList = []
    fileDictionary = {}
    for thisFile in spectrumFiles:
        thisTime = float(reTime.search(thisFile).group(1))
        fileDictionary[thisTime] = thisFile

    import collections
    ofileDictionary = collections.OrderedDict(sorted(fileDictionary.items()))

    nextTime = -999999999.9
    for thisTime, thisFile in ofileDictionary.iteritems():
        log.debug('thisTime: %(thisTime)s, thisFile: %(thisFile)s' % locals())
        if thisTime < nextTime:
            log.debug('skipping the file: %(thisFile)s' % locals())
            continue
        else:
            nextTime = thisTime + temporalResolution
            thisTime -= peakTime
            wavelengthArray, fluxArray = extract_spectra_from_file(
                log, thisFile)
            spRest = syn.ArraySpectrum(
                wave=wavelengthArray, flux=fluxArray, waveunits='angstrom', fluxunits='flam')
            try:
                log.debug("attempting to determine the rest %s-magnitude" %
                          (restFrameFilter,))
                gRest = calcphot(
                    log,
                    wavelengthArray=wavelengthArray,
                    fluxArray=fluxArray,
                    obsmode="sdss,%s" % (restFrameFilter,)
                )
            except Exception as e:
                if "Integrated flux is <= 0" in str(e):
                    log.warning(
                        "could not determine the rest-magnitude using calcphot - filter, model, time, file %s, %s, %s, %s - failed with this error: %s " %
                        (restFrameFilter, model, thisTime, thisFile, str(e),))
                    continue
                elif "Spectrum and bandpass do not fully overlap" in str(e):
                    log.warning(
                        "could not determine the rest-magnitude using calcphot - filter, model, time, file %s, %s, %s, %s - failed with this error: %s " %
                        (restFrameFilter, model, thisTime, thisFile, str(e),))
                    continue
                else:
                    log.warning(
                        "could not determine the rest-magnitude using calcphot - filter, model, time, file %s, %s, %s, %s - failed with this error: %s " %
                        (restFrameFilter, model, thisTime, thisFile, str(e),))
                pass

            for thisFilter in filters:
                strRed = "%0.2f" % (redshift,)
                spObs = spRest.redshift(redshift)
                dataDir = pathToOutputDirectory + \
                    "k_corrections/%s/%s" % (model, thisFilter)
                try:
                    log.debug(
                        "attempting to open the yaml file to append k-correction data")
                    fileName = dataDir + "/z" + \
                        str(strRed).replace(".", "pt") + ".yaml"
                    stream = file(fileName, 'a')
                except Exception as e:
                    log.critical(
                        "could not open the yaml file to append k-correction data - failed with this error: %s " % (str(e),))
                    return -1

                try:
                    log.debug(
                        "attempting to determine the magnitude of the object using calcphot - redshift, filter, model %s, %s, %s" %
                        (strRed, thisFilter, model))
                    filterObs = calcphot(
                        log,
                        wavelengthArray=spObs.wave,
                        fluxArray=spObs.flux,
                        obsmode="sdss,%s" % (thisFilter,)
                    )
                except Exception as e:
                    if "Integrated flux is <= 0" in str(e):
                        log.warning(
                            "could not determine the magnitude of the object using calcphot - redshift, filter, model %s, %s, %s - failed with this error: %s " %
                            (strRed, thisFilter, model, str(e),))
                        continue
                    elif "Spectrum and bandpass do not fully overlap" in str(e):
                        log.warning(
                            "could not determine the magnitude of the object using calcphot - redshift, filter, model %s, %s, %s - failed with this error: %s " %
                            (strRed, thisFilter, model, str(e),))
                        continue
                    elif "disjoint" in str(e):
                        log.warning(
                            "could not determine the magnitude of the object using calcphot - redshift, filter, model %s, %s, %s - failed with this error: %s " %
                            (strRed, thisFilter, model, str(e),))
                        continue
                    else:
                        log.warning(
                            "could not determine the magnitude of the object using calcphot - redshift, filter, model %s, %s, %s - failed with this error: %s " %
                            (strRed, thisFilter, model, str(e),))
                    pass
                kCor = gRest - filterObs
                kcName = 'K_%s%s' % (restFrameFilter, thisFilter,)
                thisKcor = {}
                thisKcor["Rest Frame Days"] = thisTime
                thisKcor[kcName] = kCor
                yamlList = [thisKcor]
                yaml.dump(yamlList, stream, default_flow_style=False)
                stream.close()

    return
예제 #18
0
        + T + 'kK_7.0_solar/*.txt')
    print 'Using model: ', model_fpath[0]

    #read the TMAP spectrum into a table
    colnames = ['lambda', 'F_lambda']
    in_wl = []
    in_flx = []
    with open(model_fpath[0], 'r') as f:
        for line in f:
            line = line.split()
            in_wl.append(float(line[0]))
            #convert flux from erg/cm**2/s/cm to erg/s/cm**2/A
            flx_cgs = float(line[1]) * 1e-8
            in_flx.append(flx_cgs)
    spectrum = S.ArraySpectrum(np.array(in_wl),
                               np.array(in_flx),
                               waveunits='angstrom',
                               fluxunits='flam')
    wl = in_wl
    flx = in_flx
    """
	#try using a blackbody spectrum
	#wavelengths = np.arange(1e-9, 2e-6, 0.5e-9) #meters
	
	wavelengths = [line*1e-10 for line in in_wl] #meters
	temp = float(T)*1000
	flx = [planck(w, temp ) for w in wavelengths] #W/m^3/ster
	#convert bb in W /steradian /m^3 = : convert to erg /s /steradian /Angstom
	#1W = 1x10^7 erg/s
	#1m = 1x10^10A , 1/m = 1e-10/A
	#1m^-3 = 1e-30A^-3
	flx = [val*1e7*(1e-30) for val in flx]	
예제 #19
0
    def star(self,
             opannection,
             temp=None,
             metal=None,
             logg=None,
             radius=None,
             radius_unit=None,
             database='ck04models',
             filename=None,
             w_units=None,
             f_units=None):
        """
		Get the stellar spectrum using pysynphot and interpolate onto a much finer grid than the 
		planet grid. 

		Parameters
		----------
		opannection : class picaso.RetrieveOpacities
			This is the opacity class and it's needed to get the correct wave info and raman scattering cross sections
		temp : float 
			Teff of the stellar model 
		metal : float 
			Metallicity of the stellar model 
		logg : float 
			Logg cgs of the stellar model
		radius : float 
			Radius of the star 
		radius_unit : astropy.unit
			Any astropy unit (e.g. `radius_unit=astropy.unit.Unit("R_sun")`)
		database : str 
			(Optional)The database to pull stellar spectrum from. See documentation for pysynphot. 
		filename : str 
			(Optional) Upload your own stellar spectrum. File format = two column white space (wave, flux)
		wunits : str 
			(Optional) Used for stellar file wave units 
		funits : str 
			(Optional) Used for stellar file flux units 
		"""
        #most people will just upload their thing from a database
        if (not isinstance(radius, type(None))):
            r = (radius * radius_unit).to(u.cm).value
            radius_unit = 'cm'
        else:
            r = np.nan
            radius_unit = "Radius not supplied"

        if (not isinstance(temp, type(None))):
            sp = psyn.Icat(database, temp, metal, logg)
            sp.convert("um")
            sp.convert('flam')
            wno_star = 1e4 / sp.wave[::-1]  #convert to wave number and flip
            flux_star = sp.flux[::
                                -1] * 1e8  #flip here and convert to ergs/cm3/s to get correct order

        #but you can also upload a stellar spec of your own
        elif (not isinstance(filename, type(None))):
            star = np.genfromtxt(filename, dtype=(float, float), names='w, f')
            flux = star['f']
            wave = star['w']
            #sort if not in ascending order
            sort = np.array([wave, flux]).T
            sort = sort[sort[:, 0].argsort()]
            wave = sort[:, 0]
            flux = sort[:, 1]
            if w_unit == 'um':
                WAVEUNITS = 'um'
            elif w_unit == 'nm':
                WAVEUNITS = 'nm'
            elif w_unit == 'cm':
                WAVEUNITS = 'cm'
            elif w_unit == 'Angs':
                WAVEUNITS = 'angstrom'
            elif w_unit == 'Hz':
                WAVEUNITS = 'Hz'
            else:
                raise Exception(
                    'Stellar units are not correct. Pick um, nm, cm, hz, or Angs'
                )

            #http://www.gemini.edu/sciops/instruments/integration-time-calculators/itc-help/source-definition
            if f_unit == 'Jy':
                FLUXUNITS = 'jy'
            elif f_unit == 'FLAM':
                FLUXUNITS = 'FLAM'
            elif f_unit == 'erg/cm2/s/Hz':
                flux = flux * 1e23
                FLUXUNITS = 'jy'
            else:
                raise Exception(
                    'Stellar units are not correct. Pick FLAM or Jy or erg/cm2/s/Hz'
                )

            sp = psyn.ArraySpectrum(
                wave, flux, waveunits=WAVEUNITS, fluxunits=FLUXUNITS
            )  #Convert evrything to nanometer for converstion based on gemini.edu
            sp.convert("um")
            sp.convert('flam')  #ergs/cm2/s/ang
            wno_star = 1e4 / sp.wave[::-1]  #convert to wave number and flip
            flux_star = sp.flux[::
                                -1] * 1e8  #flip and convert to ergs/cm3/s here to get correct order

        wno_planet = opannection.wno
        max_shift = np.max(
            wno_planet
        ) + 6000  #this 6000 is just the max raman shift we could have
        min_shift = np.min(
            wno_planet
        ) - 2000  #it is just to make sure we cut off the right wave ranges

        #this adds stellar shifts 'self.raman_stellar_shifts' to the opacity class
        #the cross sections are computed later
        if self.inputs['approx']['raman'] == 0:
            #do a fail safe to make sure that star is on a fine enough grid for planet case
            fine_wno_star = np.linspace(min_shift, max_shift,
                                        len(wno_planet) * 5)
            fine_flux_star = np.interp(fine_wno_star, wno_star, flux_star)
            opannection.compute_stellar_shits(fine_wno_star, fine_flux_star)
        else:
            fine_wno_star = wno_planet
            fine_flux_star = np.interp(wno_planet, wno_star, flux_star)
            opannection.unshifted_stellar_spec = fine_flux_star

        self.inputs['star']['database'] = database
        self.inputs['star']['temp'] = temp
        self.inputs['star']['logg'] = logg
        self.inputs['star']['metal'] = metal
        self.inputs['star']['radius'] = r
        self.inputs['star']['radius_unit'] = radius_unit
        self.inputs['star']['flux'] = fine_flux_star
        self.inputs['star']['wno'] = fine_wno_star
예제 #20
0
 def testsp(self):
     self.sp = S.ArraySpectrum(self.wv, self.fl, fluxunits='photlam')
     tst = self.sp(1500)
     self.assertTrue(tst == 10)
예제 #21
0
def read_source(sourcespec):
    """
    Read a spectrum

    Parameters
    ----------
    sourcespec : str
        Source spectrum specification string. Acceptable options are:
         * BB<Temperature>
         * PL<Reference Wave Angstrom>_<PL Index>
         * Flat<AB magnitude>
         * ckmod<Temperature>_<logZ>_<logg>

    Returns
    -------
    source : :py:class:`pysynphot.spectrum.ArraySourceSpectrum`
        The spectrum data.
        Has ``dtype=[('wave', '<f8'), ('flux', '<f8')]``

    Raises
    ------
    ValueError
        If attempting to use this routine to load a file, or if source spectrum
        specification string is invalid

    Notes
    -----
       The source spectrum specification string parsing is basic. Strings are
       checked to see if they start with an acceptable prefix, and then split.
       The individual constituents are converted to float, and passed to
       pysynphot. There is no checking of the values, only that they can be
       properly typecast into float. Making sure the value is accepted is left
       to the user.

    """
    if os.path.exists(sourcespec):
        message = 'File spectrum parsing is complex and requires pre-processing. Use source_synphot.source routines'
        raise ValueError(message)
    else:
        # assume sourcespec is a string and parse it, trying to interpret as:
        # simple blackbody spectrum
        if sourcespec.startswith('BB'):
            temp = sourcespec.lstrip('BB')
            try:
                temp = float(temp)
            except (TypeError, ValueError) as e:
                message = 'Source temperature {} cannot be interpreted as a float'.format(sourcespec)
                raise ValueError(message)
            bb = S.Blackbody(temp)
            bb.convert('flam')
            spec = {'wave':bb.wave, 'flux':bb.flux}

        # power-law spectrum
        elif sourcespec.startswith('PL'):
            refwave, plindex = sourcespec.lstrip('PL').split('_')
            try:
                refwave = float(refwave)
            except (TypeError, ValueError) as e:
                message = 'Reference wavelength {} cannot be interpreted as a float'.format(sourcespec)
                raise ValueError(message)
            try:
                plindex = float(plindex)
            except (TypeError, ValueError) as e:
                message = 'Power law index {} cannot be interpreted as a float'.format(sourcespec)
                raise ValueError(message)
            pl = S.PowerLaw(refwave, plindex)
            pl.convert('flam')
            spec = {'wave':pl.wave, 'flux':pl.flux}

        # flat spectrum (in f_lam, not f_nu) normalized to some ABmag
        elif sourcespec.startswith('Flat'):
            abmag = sourcespec.replace('Flat','')
            try:
                abmag = float(abmag)
            except (TypeError, ValueError) as e:
                message = 'AB mag {} cannot be interpreted as a float'.format(sourcespec)
                raise ValueError(message)
            flat = S.FlatSpectrum(abmag, fluxunits='abmag')
            flat.convert('flam')
            spec = {'wave':flat.wave, 'flux':flat.flux}

        # a Castelli-Kurucz model
        elif sourcespec.startswith('ckmod'):
            teff, logZ, logg = sourcespec.replace('ckmod','').split('_')
            try:
                teff = float(teff)
            except (TypeError, ValueError) as e:
                message = 'Source temperature {} cannot be interpreted as a float'.format(sourcespec)
                raise ValueError(message)
            try:
                logZ = float(logZ)
            except (TypeError, ValueError) as e:
                message = 'Abundance {} cannot be interpreted as a float'.format(sourcespec)
                raise ValueError(message)
            try:
                logg = float(logg)
            except (TypeError, ValueError) as e:
                message = 'Surface gravity {} cannot be interpreted as a float'.format(sourcespec)
                raise ValueError(message)
            ckmod = S.Icat('ck04models',teff, logZ,logg)
            ckmod.convert('flam')
            spec = {'wave':ckmod.wave, 'flux':ckmod.flux}

        # else give up
        else:
            message = 'Source spectrum {} cannot be parsed as input file or pre-defined type (BB, PL, Flat, ckmod)'.format(sourcespec)
            raise ValueError(message)
    spec = S.ArraySpectrum(spec['wave'], spec['flux'], name=sourcespec)
    return spec
예제 #22
0
 def setUp(self):
     self.sp=S.ArraySpectrum(N.arange(1,10000),
                             N.arange(9999)*2.5)