def testobsband(self): self.bp = S.ObsBandpass('acs,hrc,f555w') tst = self.bp(3000) assert True
# Unset the *CAM thruput stuff S.setref(comptable=None, graphtable=None) # leave the telescope area as it was S.setref(area=None) # reset the telescope area as well # Synthetic spectrum sp = S.FileSpectrum(os.path.join(pickles_path, name + '.fits')) # Apply extinction to that spectrum ext = S.Extinction(ebv, 'gal3') sp = sp * ext # Get all the magnitudes simulated_mags = {} for f in sdss_filters: bp = S.ObsBandpass("{},{}".format('sdss', f)) obs = S.Observation(sp, bp, force='taper') mag = obs.effstim("abmag") simulated_mags[f] = mag # Get the actual colours for colour in SDSS_COLOURS: f1, f2 = colour.split("-") colour_mag = simulated_mags[f1] - simulated_mags[f2] row[colour] = colour_mag # Get the colour corrections for the super filters S.setref(**getref(telescope)) for f in cam_filters:
def test_wfpc2_cont(self): bp = S.ObsBandpass('wfpc2,1,a2d7,f300w,cont#49892.0') ur = bp.unit_response() self.assertApproxFP(ur, 6.3011E-17, accuracy=1.e-4)
# bandlistfile = c['BANDS'] # bandnames,bands = readbands(bandlistfile) # except: # band = c['BAND'] # a = band.split(',') # bandnames = [a[-1]] # bands = [S.ObsBandpass(band)] try: redshifts = array(c['REDSHIFTS']) except: z = c['REDSHIFT_RANGE'] redshifts = arange(z[0], z[1], z[2]) if c.has_key('NORM_BAND'): normbandlist = c['NORM_BAND'] normbandstring = ','.join(normbandlist) normband = S.ObsBandpass(normbandstring) normvalue = c['NORM_ABMAG'] normredshift = c['NORM_REDSHIFT'] norm = [normband, normvalue, normredshift] # print norm else: norm = [] # Get cosmological parameters H0 = 70. omega_tot = 1.0 omega_m = 0.27 omega_l = 0.73 if c.has_key('H0'): H0 = c['H0'] if c.has_key('Omega_tot'): omega_tot = c['Omega_tot'] if c.has_key('Omega_m'): omega_m = c['Omega_m'] if c.has_key('Omega_lambda'): omega_l = c['Omega_lambda']
'F160W': 15369.175708965562, 'F435W': 4328.256914042873, 'F606W': 5921.658489236346, 'F775W': 7693.297933335407, 'F814W': 8058.784799323767, 'VISTAH': 1.6433e+04 } if False: import pysynphot as S n = 1.e-20 spec = S.FlatSpectrum(n, fluxunits='flam') photflam = {} photplam = {} for filter in ['F098M', 'F105W', 'F110W', 'F125W', 'F140W', 'F160W']: bp = S.ObsBandpass('wfc3,ir,%s' % (filter.lower())) photplam[filter] = bp.pivot() obs = S.Observation(spec, bp) photflam[filter] = n / obs.countrate() # for filter in ['F435W', 'F606W', 'F775W', 'F814W']: bp = S.ObsBandpass('acs,wfc1,%s' % (filter.lower())) photplam[filter] = bp.pivot() obs = S.Observation(spec, bp) photflam[filter] = n / obs.countrate() class GrismFLT(object): """ Scripts for simple modeling of individual grism FLT images
def get_pbmodel(pbnames, model, pbfile=None, mag_type=None, mag_zero=0.): """ Converts passband names ``pbnames`` into passband models based on the mapping of name to ``pysynphot`` ``obsmode`` strings in ``pbfile``. Parameters ---------- pbnames : array-like List of passband names to get throughput models for Each name is resolved by first looking in ``pbfile`` (if provided) If an entry is found, that entry is treated as an ``obsmode`` for pysynphot. If the entry cannot be treated as an ``obsmode,`` we attempt to treat as an ASCII file. If neither is possible, an error is raised. model : :py:class:`WDmodel.WDmodel.WDmodel` instance The DA White Dwarf SED model generator All the passbands are interpolated onto the wavelengths of the SED model. pbfile : str, optional Filename containing mapping between ``pbnames`` and ``pysynphot`` ``obsmode`` string, as well as the standard that has 0 magnitude in the system (either ''Vega'' or ''AB''). The ``obsmode`` may also be the fullpath to a file that is readable by ``pysynphot`` mag_type : str, optional One of ''vegamag'' or ''abmag'' Used to specify the standard that has mag_zero magnitude in the passband. If ``magsys`` is specified in ``pbfile,`` that overrides this option. Must be the same for all passbands listed in ``pbname`` that do not have ``magsys`` specified in ``pbfile`` If ``pbnames`` require multiple ``mag_type``, concatentate the output. mag_zero : float, optional Magnitude of the standard in the passband If ``magzero`` is specified in ``pbfile,`` that overrides this option. Must be the same for all passbands listed in ``pbname`` that do not have ``magzero`` specified in ``pbfile`` If ``pbnames`` require multiple ``mag_zero``, concatentate the output. Returns ------- out : dict Output passband model dictionary. Has passband name ``pb`` from ``pbnames`` as key. Raises ------ RuntimeError If a bandpass cannot be loaded Notes ----- Each item of ``out`` is a tuple with * ``pb`` : (:py:class:`numpy.recarray`) The passband transmission with zero throughput entries trimmed. Has ``dtype=[('wave', '<f8'), ('throughput', '<f8')]`` * ``transmission`` : (array-like) The non-zero passband transmission interpolated onto overlapping model wavelengths * ``ind`` : (array-like) Indices of model wavelength that overlap with this passband * ``zp`` : (float) mag_type zeropoint of this passband * ``avgwave`` : (float) Passband average/reference wavelength ``pbfile`` must be readable by :py:func:`WDmodel.io.read_pbmap` and must return a :py:class:`numpy.recarray` with``dtype=[('pb', 'str'),('obsmode', 'str')]`` If there is no entry in ``pbfile`` for a passband, then we attempt to use the passband name ``pb`` as ``obsmode`` string as is. Trims the bandpass to entries with non-zero transmission and determines the ``VEGAMAG/ABMAG`` zeropoint for the passband - i.e. ``zp`` that gives ``mag_Vega/AB=mag_zero`` in all passbands. See Also -------- :py:func:`WDmodel.io.read_pbmap` :py:func:`WDmodel.passband.chop_syn_spec_pb` """ # figure out the mapping from passband to observation mode if pbfile is None: pbfile = 'WDmodel_pb_obsmode_map.txt' pbfile = io.get_pkgfile(pbfile) pbdata = io.read_pbmap(pbfile) pbmap = dict(list(zip(pbdata.pb, pbdata.obsmode))) sysmap = dict(list(zip(pbdata.pb, pbdata.magsys))) zeromap = dict(list(zip(pbdata.pb, pbdata.magzero))) # setup the photometric system by defining the standard and corresponding magnitude system if mag_type not in ('vegamag', 'abmag', None): message = 'Magnitude system must be one of abmag or vegamag' raise RuntimeError(message) try: mag_zero = float(mag_zero) except ValueError as e: message = 'Zero magnitude must be a floating point number' raise RuntimeError(message) # define the standards vega = S.Vega vega.convert('flam') ab = S.FlatSpectrum(0., waveunits='angstrom', fluxunits='abmag') ab.convert('flam') # defile the magnitude sysem if mag_type == 'vegamag': mag_type= 'vegamag' else: mag_type = 'abmag' out = OrderedDict() for pb in pbnames: standard = None # load each passband obsmode = pbmap.get(pb, pb) magsys = sysmap.get(pb, mag_type) synphot_mag = zeromap.get(pb, mag_zero) if magsys == 'vegamag': standard = vega elif magsys == 'abmag': standard = ab else: message = 'Unknown standard system {} for passband {}'.format(magsys, pb) raise RuntimeError(message) loadedpb = False # treat the passband as a obsmode string try: bp = S.ObsBandpass(obsmode) loadedpb = True except ValueError: message = 'Could not load pb {} as an obsmode string {}'.format(pb, obsmode) warnings.warn(message, RuntimeWarning) loadedpb = False # if that fails, try to load the passband interpreting obsmode as a file if not loadedpb: try: bandpassfile = io.get_filepath(obsmode) bp = S.FileBandpass(bandpassfile) loadedpb = True except Exception as e: message = 'Could not load passband {} from obsmode or file {}'.format(pb, obsmode) warnings.warn(message, RuntimeWarning) loadedpb = False if not loadedpb: message = 'Could not load passband {}. Giving up.'.format(pb) raise RuntimeError(message) avgwave = bp.avgwave() if standard.wave.min() > model._wave.min(): message = 'Standard does not extend past the blue edge of the model' warnings.warn(message, RuntimeWarning) if standard.wave.max() < model._wave.max(): message = 'Standard does not extend past the red edge of the model' warnings.warn(message, RuntimeWarning) # interpolate the standard onto the model wavelengths sinterp = interp1d(standard.wave, standard.flux, fill_value='extrapolate') standard_flux = sinterp(model._wave) standard = np.rec.fromarrays([model._wave, standard_flux], names='wave,flux') # cut the passband to non-zero values and interpolate onto overlapping standard wavelengths outpb, outzp = chop_syn_spec_pb(standard, synphot_mag, bp, model) # interpolate the passband onto the standard's wavelengths transmission, ind = interp_passband(model._wave, outpb, model) # save everything we need for this passband out[pb] = (outpb, transmission, ind, outzp, avgwave) return out
def setUp(self): self.sp=S.ObsBandpass('acs,hrc,f555w')
#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) #plt.xlim(3000, 10000) #plt.ylim(0, 0.6e10) #plt.show() obs_U = S.Observation(red_spectrum, S.ObsBandpass('U')) obs_B = S.Observation(red_spectrum, S.ObsBandpass('B')) obs_V = S.Observation(red_spectrum, S.ObsBandpass('V')) obs_I = S.Observation(red_spectrum, S.ObsBandpass('I')) U_min_B = obs_U.effstim(magsystem) - obs_B.effstim(magsystem) B_min_V = obs_B.effstim(magsystem) - obs_V.effstim(magsystem) V_min_I = obs_V.effstim(magsystem) - obs_I.effstim(magsystem) #paper1: corrections that were supposed to be applied B_min_V+=0.010 V_min_I-=0.002
#!/usr/bin/env python from numpy import * from pygoods import * import pysynphot as S import magredshift as MR from pysynphot import Extinction import myutil import arrayspec as A import simutil Lsun = 3.826e33 # erg / sec pc_cm = 30.857e17 # 1 parsec in cm #uni1500 = S.FileBandpass('uni1500.bp') uni1500 = S.Box(1500., 100.) iband = S.ObsBandpass('acs,wfc2,f775w') zband = S.ObsBandpass('acs,wfc2,f850lp') #sp10 = S.FileSpectrum('mylbg_sfr10.sed') def simkcorr(sp, absmag_rest, restband, obsband, z, lya_ew): # defined as m_1 = M_2 + kcorr # m_1: apparent magnitude in observed band # M_2: absolute magnitude in rest-frame band # assumes BC03 model: model flux unit is in L_solar/angstrom #sp = S.FileSpectrum(spec) tenpc = 4. * pi * (10. * pc_cm)**2 # 10 parsec in centimeter absmag = A.ABmag(sp, restband) spn = sp * 10.**( (absmag_rest - absmag) / -2.5) # normalize sp to absmag_rest spn = spn * tenpc # get luminosity
# 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 for colour in SDSS_COLOURS: f1, f2 = colour.split("-") colour_mag = simulated_mags["hcam_{}".format(f1)] - simulated_mags["hcam_{}".format(f2)] row[colour] = colour_mag # Magnitudes for f in ucam_filters: bp = S.ObsBandpass("{},{},{}".format(ucam_tel,'ucam',f)) obs = S.Observation(sp, bp, force='taper')
def makebp(mode): try: bp = S.ObsBandpass(mode) except KeyError as e: raise AssertionError(e.message)
def uvj_diagram(u='galaxy_u.fits', v='galaxy_v.fits', j='galaxy_j.fits', target='galaxy', file_name='galaxy*.fits', size=200, x0=1000, y0=1000): """ Function for plotting a spatially resolved UVJ Diagram of an input target, while comparing with EAZY templates. INPUTS: u: Fits file of the image in the U band. v: Fits file of the image in the V band. j: Fits file of the image in the J band. target: The name of the target, to be used in the output files. file_name: General form of the file names that contain the UVJ images. size: Size of the slice to plot only part of the original image. x0: Center of the x-coordinate of the slice. y0: Center of the y-coordinate of the slice. KEYWORDS: PLOT: Set this keyword to plot the UVJ diagram. OUTPUTS: Plot of the UVJ diagram. """ from grizli import utils import numpy as np import astropy.io.fits as pyfits import matplotlib.pyplot as plt import glob import pysynphot as S slx = slice(x0 - size, x0 + size) sly = slice(y0 - size, y0 + size) u_im = pyfits.open(u) v_im = pyfits.open(v) j_im = pyfits.open(j) for ext in [0, 1]: if 'PHOTPLAM' in u_im[ext].header: u_lam = u_im[ext].header['PHOTPLAM'] break for ext in [0, 1]: if 'PHOTPLAM' in v_im[ext].header: v_lam = v_im[ext].header['PHOTPLAM'] break for ext in [0, 1]: if 'PHOTPLAM' in j_im[ext].header: j_lam = j_im[ext].header['PHOTPLAM'] break fu = u_im['SCI'].data[sly, slx] * u_im[1].header['IM2FLAM'] * (u_lam**2) fv = v_im['SCI'].data[sly, slx] * v_im[1].header['IM2FLAM'] * (v_lam**2) fj = j_im['SCI'].data[sly, slx] * j_im[1].header['IM2FLAM'] * (j_lam**2) fu_error = u_im['ERR'].data[sly, slx] * u_im[1].header['IM2FLAM'] * (u_lam **2) fv_error = v_im['ERR'].data[sly, slx] * v_im[1].header['IM2FLAM'] * (v_lam **2) fj_error = j_im['ERR'].data[sly, slx] * j_im[1].header['IM2FLAM'] * (j_lam **2) u_v_err = (2.5 / np.log(10)) * np.sqrt((fu_error / fu)**2 + (fv_error / fv)**2) v_j_err = (2.5 / np.log(10)) * np.sqrt((fj_error / fj)**2 + (fv_error / fv)**2) u_v = -2.5 * np.log10(fu / fv) v_j = -2.5 * np.log10(fv / fj) mask = (u_v_err < 0.1) & (v_j_err < 0.1) templ = utils.load_templates(full_line_list=[], line_complexes=False, fsps_templates=True, alf_template=True) files = glob.glob(file_name) files.sort() images = {} bandpasses = {} for file in files: im = pyfits.open(file) filt = utils.get_hst_filter(im[0].header) for ext in [0, 1]: if 'PHOTMODE' in im[ext].header: bandpasses[filt.lower()] = S.ObsBandpass( im[ext].header['PHOTMODE'].replace(' ', ',')) break images[filt.lower()] = im['SCI'].data template_fluxes = {} for f in bandpasses: template_fluxes[f] = np.zeros(len(templ)) # templates from EAZY for i, t in enumerate(templ): t_z = templ[t].zscale(0.03) for f in bandpasses: template_fluxes[f][i] = t_z.integrate_filter(bandpasses[f]) s = templ.keys() uv = -2.5 * np.log10(template_fluxes[u] / template_fluxes[v]) vj = -2.5 * np.log10(template_fluxes[v] / template_fluxes[j]) fig, ax = plt.subplots(figsize=(12, 10)) plt.plot(v_j[mask], u_v[mask], 'kx', ms=1, zorder=-5) for i, lab in enumerate(s): plt.scatter(vj[i], uv[i], label=lab) box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.8, box.height]) ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) plt.xlabel('V-J [observed] (AB mag)'.format(v, j)) plt.ylabel('U-V [observed] (AB mag)'.format(u, v)) plt.title('UVJ Diagram {0}'.format(target)) plt.show() #-----------------------------------------------------------------------------
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')
def test_c1280(self): self.obsmode = 'cos,fuv,g140l,c1280' self.tda['obsmode'] = self.obsmode bp = S.ObsBandpass(self.obsmode) obs = S.Observation(S.BlackBody(5500), bp)
def get_col_correction(telescope, instrument, filter, teff, logg, plot=False): S.setref(**getref(telescope)) bp = S.ObsBandpass('{},{},{}'.format(telescope, instrument, filter)) bp_HCAM_GTC = S.ObsBandpass( 'hcam,gtc,{}'.format(filter.split('_')[0] + '_s')) table_fname = get_fname(teff, logg) teff, logg = get_teff_logg(table_fname) table = pd.read_csv(table_fname, delim_whitespace=True, comment='#', names=['WAVELENGTH (ANGSTROM)', 'FLUX (ERG/CM2/S/A)']) # drop duplicate wavelengths. WTF are they here Koester? table.drop_duplicates(subset='WAVELENGTH (ANGSTROM)', inplace=True) # create pysynphot spectrum sp = S.ArraySpectrum(table['WAVELENGTH (ANGSTROM)'], table['FLUX (ERG/CM2/S/A)'], fluxunits='flam', waveunits='Angstrom') obs = S.Observation(sp, bp, force='taper') obs_HCAM_GTC = S.Observation(sp, bp_HCAM_GTC, force='taper') tot_mag = obs.effstim('abmag') col_term = obs_HCAM_GTC.effstim('abmag') - tot_mag if plot: # Plotting stuff limits = (bp.wave.min(), bp.wave.max()) cut_table = table[(table['WAVELENGTH (ANGSTROM)'] < limits[1]) & (table['WAVELENGTH (ANGSTROM)'] > limits[0])] fig, ax = plt.subplots() ax2 = ax.twinx() ax2.plot(bp.wave, bp.throughput, color='red', linestyle='--', label='{}, {} Throughput'.format(instrument, telescope)) ax2.plot(bp_HCAM_GTC.wave, bp_HCAM_GTC.throughput, color='black', linestyle='--', label='HCAM, GTC Throughput') ax.plot(obs.wave, obs.flux, color='red', label='{}, {} stimulation'.format(instrument, telescope)) ax.plot(obs_HCAM_GTC.wave, obs_HCAM_GTC.flux, color='black', label='HCAM, GTC stimulation') ax.step(cut_table['WAVELENGTH (ANGSTROM)'], cut_table['FLUX (ERG/CM2/S/A)'], color='lightgrey', label='Raw Spectrum') ax.set_title( "Teff: {} || log(g): {} || detected magnitude: {:.3f} || Color {:.3f}" .format(teff, logg, tot_mag, col_term)) ax.set_xlabel("Wavelength, Angstroms") ax.set_ylabel("Flux, erg/cm2/s/A") ax.set_xlim(limits) fig.legend() plt.tight_layout() plt.show() return col_term
def apply_binning(tab_file, seg_file, mask_file, obj_name): """ Function to bin images according to the input "seg_file", obtained with Voronoi_Binning Input for this function is the output from the Voronoi_Binning function. """ import glob import astropy.units.astrophys as u import numpy as np import astropy.io.fits as pyfits from grizli import utils import pysynphot as S files = glob.glob('*{0}*fits.gz'.format(obj_name)) files.sort() res = {} master_table = tab_file bandpasses = {} h = {} for file in files: im = pyfits.open(file) filt = utils.get_hst_filter(im[0].header) for ext in [0,1]: if 'PHOTMODE' in 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() h['{0}_photfnu'.format(filt.lower())] = my_photfnu h['{0}_photflam'.format(filt.lower())] = my_photflam for file in files: im = pyfits.open(file) f = utils.get_hst_filter(im[0].header).lower() im2mujy = h['{0}_photfnu'.format(f)] im2flam = h['{0}_photflam'.format(f)] print(f,im2mujy,im2flam) res[f],data_tab = bin_image(im, tab_file, seg_file, mask_file) primary_extn = pyfits.PrimaryHDU() sci_extn = pyfits.ImageHDU(data=res[f]['image_flux'].astype(np.float32),name='SCI') err_extn = pyfits.ImageHDU(data=res[f]['image_err'].astype(np.float32),name='ERR') hdul = pyfits.HDUList([primary_extn, sci_extn, err_extn]) for ext in [0,1]: for k in im[ext].header: if k not in hdul[ext].header: if k in ['COMMENT','HISTORY','']: continue hdul[ext].header[k] = im[ext].header[k] hdul[1].header['IM2FLAM'] = (im2flam, 'Convert images to flambda cgs') hdul[1].header['IM2MUJY'] = (im2mujy, 'Convert images to fnu, microJy') hdul.writeto('binned_{0}_{1}_image.fits'.format(obj_name,f), output_verify='fix',overwrite=True) # bin_flux and bin_error of each filter to append to the master table master_table['{0}_flux'.format(f)] = res[f]['bin_flux']*im2mujy master_table['{0}_flux'.format(f)].unit = u.Jy*1e-6 master_table['{0}_err'.format(f)] = res[f]['bin_err']*im2mujy master_table['{0}_err'.format(f)].unit = u.Jy*1e-6 # master_table.remove_columns(['flux','err','area']) master_table.write('binned_{0}_master_table.fits'.format(obj_name), overwrite=True) return master_table
def bandpass(self): import pysynphot as ps ps.setref(**self.REFS) obsmode = "wfc3,ir," + self.filter.lower() return ps.ObsBandpass(obsmode)
def read_passband(pb, pbzp=None): """ Read a passband. Parameters ---------- pb : str pysynphot obsmode or obsmode listed in `pbzptmag.txt` pbzp : float, optional AB magnitude zeropoint of the passband Returns ------- pb : :py:class:`pysynphot.ArrayBandpass` or :py:class:`pysynphot.obsbandpass.ObsModeBandpass` The passband data. Has ``dtype=[('wave', '<f8'), ('throughput', '<f8')]`` pbzp : float passband AB zeropoint - potentially NaN if this was not supplied. If NaN this can be computed assuming an AB source - i.e. a source with a flux density of 3631 jy has magnitude = 0 in the bandpass. Notes ----- Note that this is a straight read of a single passband from a file. The zeropoint returned is whatever was provided (even if the value is not useful) or NaN. To load the passband and get the correct zeropoint, use :py:func:`source_synphot.passband.load_pbs` See Also -------- :py:func:`astropy.table.Table.read` :py:func:`pysynphot.ObsBandpass` """ if pbzp is None: pbzp = np.nan try: out = S.ObsBandpass(pb) pbzp = np.nan except ValueError as e: infile = os.path.join('passbands','pbzptmag.txt') pbzptfile = get_pkgfile(infile) pbzpt = at.Table.read(pbzptfile, format='ascii') ind = (pbzpt['obsmode'] == pb) nmatch_pb = len(pbzpt['passband'][ind]) if nmatch_pb == 1: pbname = pb if not np.isnan(pbzpt['ABzpt'][ind][0]): pb = pbzpt['passband'][ind][0] pbzp = pbzpt['ABzpt'][ind][0] else: pbzp = np.nan pb = os.path.join('passbands', pb) try: pb = get_pkgfile(pb) except (OSError, IOError) as e: out = None pbzp = np.nan message = 'Passband {} not located in the passbands directory'.format(pb) pass elif nmatch_pb == 0: # we'll just see if this passband is a file and load it as such pbname = None message = 'Passband {} is not listed in pbzptmag file.'.format(pb) pass else: # pb is not unique out = None message = 'Passband {} is not uniquely listed in pbzptmag file.'.format(pb) if os.path.exists(pb): if pbname is None: pbname = os.path.basename(pb) # we either loaded the passband name from the lookup table or we didn't get a match pbdata = at.Table.read(pb, names=('wave','throughput'), format='ascii') out = S.ArrayBandpass(pbdata['wave'], pbdata['throughput'], waveunits='Angstrom', name=pbname) else: out = None message = 'Passband {} could not be loaded from any source.'.format(pb) if out is None: raise ValueError(message) try: pbzp = float(pbzp) except TypeError as e: message = 'Supplied zeropoint {} could not be interepreted as a float.'.format(zp) warnings.warn(message, RuntimeWarning) pbzp = np.nan return out, pbzp
import pdb from astropy.table import Table import os import matplotlib.pyplot as plt pynrc.setup_logging('WARN', verbose=False) innerGrid = np.arange(0, 1.6, 0.1) #innerGrid = np.arange(1.5,1.6,0.1) outerGrid = np.arange(1.6, 3.2, 0.2) rGrid = np.hstack([innerGrid, outerGrid]) spFlat = S.FlatSpectrum(5, fluxunits='flam') bpK = S.ObsBandpass('johnson,k') for oneFilt, oneMask in zip(['F444W', 'F200W'], ['MASK430R', 'MASK210R']): satArr, sensArr = [], [] for onePt in rGrid: # print('Working on r={}'.format(onePt)) nrc = pynrc.NIRCam(filter=oneFilt, pupil='CIRCLYOT', mask=oneMask, wind_mode='WINDOW', xpix=320, ypix=320, offset_r=onePt, offset_theta=90, read_mode='RAPID',
def setUp(self): self.sp = S.BlackBody(30000) self.bp = S.ObsBandpass('johnson,v')
def get_stellar_spectrum(planet_table_entry, wvs, R, model='Castelli-Kurucz', verbose=False): ''' A function that returns the stellar spectrum for a given spectral type Inputs: planet_table_entry - An entry from a Universe Planet Table wvs - The wavelengths at which you want the spectrum. Can be an array [microns] R - The spectral resolving power that you want [int or float] Model - The stellar spectrum moodels that you want. [string] Outputs: spectrum - returns the stellar spectrum at the desired wavelengths [photons/s/cm^2/A] ''' if model == 'pickles': #Get the pickles spectrum in units of photons/s/cm^2/angstrom. #Wavelength units are microns sp = get_pickles_spectrum(planet_table_entry['StarSpT'], verbose=verbose) #pysynphot Normalizes everthing to have Vmag = 0, so we'll scale the #stellar spectrum by the Vmag starVmag = planet_table_entry['StarVmag'] scaling_factor = 10**(starVmag / -2.5) full_stellar_spectrum = sp.flux * scaling_factor stellar_spectrum = [] #If wvs is a float then make it a list for the for loop if isinstance(wvs, float): wvs = [wvs] #Now get the spectrum! for wv in wvs: #Wavelength sampling of the pickles models is at 5 angstrom R_in = wv / 0.0005 #Down-sample the spectrum to the desired wavelength ds = downsample_spectrum(full_stellar_spectrum, R_in, R) #Interpolate the spectrum to the wavelength we want stellar_spectrum.append(si.interp1d(sp.wave, ds)(wv)) stellar_spectrum = np.array(stellar_spectrum) elif model == 'Castelli-Kurucz': # For now we're assuming a metallicity of 0, because exosims doesn't # provide anything different #The current stellar models do not like log g > 5, so we'll force it here for now. star_logG = planet_table_entry['StarLogg'] if star_logG > 5.0: star_logG = 5.0 #The current stellar models do not like Teff < 3500, so we'll force it here for now. star_Teff = planet_table_entry['StarTeff'] if star_Teff < 3500: star_Teff = 3500 # Get the Castelli-Kurucz models sp = get_castelli_kurucz_spectrum(star_Teff, 0., star_logG) # The flux normalization in pysynphot are all over the place, but it allows # you to renormalize, so we will do that here. We'll normalize to the Vmag # of the star, assuming Johnsons filters sp_norm = sp.renorm(planet_table_entry['StarVmag'], 'vegamag', ps.ObsBandpass('johnson,v')) # we normally want to put this in the get_castelli_kurucz_spectrum() function but the above line doens't work if we change units sp_norm.convert("Micron") sp_norm.convert("photlam") stellar_spectrum = [] #If wvs is a float then make it a list for the for loop if isinstance(wvs, float): wvs = [wvs] #Now get the spectrum! for wv in wvs: #Get the wavelength sampling of the pysynphot sectrum dwvs = sp_norm.wave - np.roll(sp_norm.wave, 1) dwvs[0] = dwvs[1] #Pick the index closest to our wavelength. ind = np.argsort(np.abs((sp_norm.wave - wv)))[0] dwv = dwvs[ind] R_in = wv / dwv #Down-sample the spectrum to the desired wavelength ds = downsample_spectrum(sp_norm.flux, R_in, R) #Interpolate the spectrum to the wavelength we want stellar_spectrum.append(si.interp1d(sp_norm.wave, ds)(wv)) stellar_spectrum = np.array(stellar_spectrum) else: if verbose: print("We only support 'pickles' models for now") return -1 return stellar_spectrum
os.path.join(os.getcwd(), "..", "cdbs", "grid", "phoenix", "catalog.fits")) teff, Z, logg = np.array(()), np.array(()), np.array(()) with pyfits.open(grid_file) as inf: indices = inf[1].data.field('INDEX') for row in indices: items = row.split(",") teff = np.append(teff, float(items[0])) Z = np.append(Z, float(items[1])) logg = np.append(logg, float(items[2])) return np.array( (np.unique(Z), np.unique(logg), np.unique(teff), np.arange(-5.5, 16.0))) norm_bandpass = ps.ObsBandpass('johnson,i') coords = get_grid_points() print(coords) bandpasses = {} result_arrays = {} instruments = InstrumentList() print("{}: Making Bandpasses...".format(time.ctime())) for instrument in instruments: my_instrument = instruments[instrument]() bandpasses[instrument.lower()] = {} result_arrays[instrument.lower()] = {} for mode in modes[instrument.lower()]: for filter in filters[instrument.lower()][mode]: print("\t{}: {},{},{},{}".format( time.ctime(), instrument, mode, filter,
def load_passbands(self, passbands={}): """ Load passbands either from pysynphot or check for an equivalent file in the default filter directory. """ # Load default filters first filters = self.filters message = 'Loading {source} bandpasses...' print(message.format(source='wfc3,uvis')) for bp in filters['hst']['wfc3']['uvis']: name = 'wfc3,uvis1,'+bp bpmodel = S.ObsBandpass(name) self.bandpass[name] = bpmodel self.bandpass_names.append(name) print(message.format(source='wfc3,ir')) for bp in filters['hst']['wfc3']['ir']: name = 'wfc3,ir,'+bp bpmodel = S.ObsBandpass(name) self.bandpass[name] = bpmodel self.bandpass_names.append(name) print(message.format(source='acs,wfc')) for bp in filters['hst']['acs']['wfc']: name = 'acs,wfc,'+bp bpmodel = S.ObsBandpass(name) self.bandpass[name] = bpmodel self.bandpass_names.append(name) print(message.format(source='acs,sbc')) for bp in filters['hst']['acs']['sbc']: name = 'acs,sbc,'+bp bpmodel = S.ObsBandpass(name) self.bandpass[name] = bpmodel self.bandpass_names.append(name) print(message.format(source='swift,uvot')) for bp in filters['swift']['uvot']: file = self.options['dirs']['filters']+'/SWIFT.'+bp.upper()+'.dat' name = 'swift,uvot,'+bp wave,transmission = np.loadtxt(file, unpack=True) bpmodel = S.ArrayBandpass(wave, transmission, name=name, waveunits='Angstrom') bpmodel = S.ObsBandpass(name) self.bandpass[name] = bpmodel self.bandpass_names.append(name) print(message.format(source='johnson')) for bp in johnson_bandpasses: name = 'johnson,'+bp bpmodel = S.ObsBandpass(name) self.bandpass[name] = bpmodel self.bandpass_names.append(name) print(message.format(source='sdss')) for bp in sdss_bandpasses: name = 'sdss,'+bp bpmodel = S.ObsBandpass(name) self.bandpass[name] = bpmodel self.bandpass_names.append(name) # Now if there are other passbands, load them individually # Must be formatted as dict with {name: filename} for bp in passbands.keys(): print(message.format(source=bp)) file = passbands[bp] wave,transmission = np.loadtxt(file, unpack=True) bpmodel = S.ArrayBandpass(wave, transmission, name=bp, waveunits='Angstrom') self.bandpass[bp] = bpmodel self.bandpass_names.append(bp)
ulirg_num = ["1", "2", "3", "4", "5"] ulirg_names = ["1", "2", "3", "4", "5"] filters = ['F125', 'F140', 'F150', 'F165'] data_dir = Path('./data/') params = [ 'ulirg', 'x_plot', 'y_plot', 'A', 'b', 'm', 'A_err', 'b_err', 'm_err' ] import pysynphot as S band_names = ['f125lp', 'f140lp', 'f150lp', 'f165lp'] bands = [S.ObsBandpass('acs,sbc,%s' % band) for band in band_names] waves = [band.wave for band in bands] from bokeh.models.widgets import Button s button = Button(label="ULIRG fitting method for LYA", button_type='success') pre = PreText(text="""details are at http://homepages.spa.umn.edu/~sourabh/projects/docs/build/html/index.html?""", width=300, height=100) def plot_lya(data_dir, filter_name, x_range, y_range):
def make_cluster_rates(self, masses, instrument, filter, bandpass=None, refs=None): try: coords = np.load(os.path.join(self.gridpath, 'input.npy'), allow_pickle=True) except UnicodeError: coords = np.load(os.path.join(self.gridpath, 'input.npy'), allow_pickle=True, encoding='bytes') m, t, g, i = self.get_star_info() temps = np.interp(masses, m, t) gravs = np.interp(masses, m, g) mags = np.interp(masses, m, i) metals = np.full_like(mags, self.metallicity) if os.path.exists( os.path.join( self.gridpath, 'result_{}_{}.npy'.format(instrument.lower(), filter.lower()))): values = np.load( os.path.join( self.gridpath, 'result_{}_{}.npy'.format(instrument.lower(), filter.lower()))) interpolation_function = RegularGridInterpolator( tuple([x for x in coords]), values) try: countrates = interpolation_function( np.array((metals, gravs, temps, mags)).T) except ValueError as v: self.log('error', 'Exception caught when interpolating: {}'.format(v)) min_mag = coords[-1][0] max_mag = coords[-1][-1] interpolation_function = RegularGridInterpolator( tuple([x for x in coords]), values, bounds_error=False, fill_value=0.) mags_min = np.full_like(mags, min_mag) mags_max = np.full_like(mags, max_mag) countrates = interpolation_function( np.array((metals, gravs, temps, mags)).T) countrates_min = interpolation_function( np.array((metals, gravs, temps, mags_min)).T) countrates_min = countrates_min * np.power( 10, -(mags - min_mag) / 2.512) countrates_max = interpolation_function( np.array((metals, gravs, temps, mags_max)).T) countrates_max = countrates_max * np.power( 10, -(mags - max_mag) / 2.512) countrates[np.where( mags < mags_min)] = countrates_min[np.where( mags < mags_min)] countrates[np.where( mags > mags_max)] = countrates_max[np.where( mags > mags_max)] else: self.log( 'warning', 'Could not find result file "result_{}_{}.npy"'.format( instrument.lower(), filter.lower())) import pysynphot as ps countrates = np.array(()) ps.setref(**refs) johnson_i = ps.ObsBandpass('johnson,i') for te, log_g, z, j_i in zip(temps, gravs, metals, mags): spectrum = ps.Icat('phoenix', te, z, log_g) spectrum = spectrum.renorm(j_i, 'vegamag', johnson_i) obs = ps.Observation(spectrum, bandpass, binset=spectrum.wave) countrates = np.append(countrates, obs.countrate()) self.log( 'info', 'Manually created star {} of {}'.format( len(countrates), len(temps))) return countrates
refimage = '../MACS1149/Catalog/MACS1149-F140W_drz_sci.fits' #files=files[:1] FLT = {} for i, file in enumerate(files): print '%d/%d %s' % (i + 1, len(files), file) g = mywfc3.flt.model.GrismFLT(file=file, refimage=refimage) FLT[file] = g ### Full model import pysynphot as S xarr = np.arange(8000, 1.9e4, 40) beta = -0.5 yarr = (xarr / 1.4e4)**beta * 10 bp = S.ObsBandpass('wfc3,ir,f140w') spec = S.ArraySpectrum(xarr, yarr, fluxunits='flam').renorm(1, 'flam', bp) for i, file in enumerate(files): #status = self.compute_model(x=281.13, y=856.8, sh=[20,20]) print '%d/%d %s\n' % (i + 1, len(files), file) self = FLT[file] self.full_model *= 0 skip = 40 for xs in range(skip, 901, skip): for ys in range(skip, 976, skip): print '\x1b[1A\x1b[1M' + '%d %d' % (xs, ys) for beam in 'ABCD': status = self.compute_model(x=xs, y=ys, sh=[skip / 2, skip / 2],
def setUp(self): self.sp = S.FlatSpectrum(1) self.bp = S.ObsBandpass('johnson,v')
table['FLUX (ERG/CM2/S/A)'], fluxunits='flam', waveunits='Angstroms') # Storage dict mags = {} if observation == 'UCAM': # This is the bandpass in the relevant lightpath telescope, instrument = "ntt", "ucam" # Setup the *CAM S.setref(**getref(telescope)) for filt in filters: # Get the lightpath bp = S.ObsBandpass('{},{},{}'.format(telescope, instrument, filt)) # Run the spectrum through the bandpass. Should include atmosphere? obs = S.Observation(sp, bp, force="taper") # Convert to magnitude ADU_flux = obs.countrate() mag = obs.effstim('abmag') mags[filt] = mag print("Band: {}".format(filt)) print("Countrate: {:.3f}".format(ADU_flux)) print("abmag: {:.3f}\n".format(mag)) elif observation == 'SDSS':
# --- # jupyter: # jupytext_format_version: '1.2' # kernelspec: # display_name: Python [conda env:astroconda] # language: python # name: conda-env-astroconda-py # language_info: # codemirror_mode: # name: ipython # version: 3 # file_extension: .py # mimetype: text/x-python # name: python # nbconvert_exporter: python # pygments_lexer: ipython3 # version: 3.5.1 # --- import numpy as np import pysynphot as S bp1 = S.ObsBandpass('acs,wfc1,f555w') bp1.unit_response() bp1.obsmode.modes S.ObsBandpass?
def etc_uh_roboAO(mag, filt_name, tint, sq_aper_diam=0.3, phot_sys='Vega', spec_res=100, seeing_limited=False): """ Exposure time calculator for a UH Robo-AO system and a NIR IFU spectrograph. phot_sys - 'Vega' (default) or 'AB' """ ifu_throughput = 0.35 #ao_throughput = 0.55 ao_throughput = 0.76 # New Design tel_throughput = 0.85**2 if seeing_limited: sys_throughput = ifu_throughput * tel_throughput else: sys_throughput = ifu_throughput * ao_throughput * tel_throughput # TO DO Need to add telescope secondary obscuration to correct the area. tel_area = math.pi * (2.22 * 100. / 2.)**2 # cm^2 for UH 2.2m tel sec_area = math.pi * (0.613 * 100. / 2.)**2 # cm^2 for UH 2.2m tel hole/secondary obscuration tel_area -= sec_area read_noise = 3.0 # electrons dark_current = 0.01 # electrons s^-1 # Get the filter if filt_name == 'Z' or filt_name == 'Y': filt = get_ukirt_filter(filt_name) else: filt = pysynphot.ObsBandpass(filt_name) # Calculate the wave set for the IFU. Include Nyquist sampled pixels. dlamda = (filt.avgwave() / spec_res) / 2.0 ifu_wave = np.arange(filt.wave.min(), filt.wave.max()+dlamda, dlamda) # Estimate the number of pixels across our spectrum. npix_spec = len(ifu_wave) # Get the Earth transmission spectrum. Sample everything # onto this grid. earth_trans = read_mk_sky_transmission() # Get the Earth background emission spectrum earth_bkg = read_mk_sky_emission_ir() earth_bkg.resample(ifu_wave) # Convert to Vega if in AB if phot_sys != 'Vega': mag += Vega_to_AB[filt_name] # Assume this star is an A0V star, so just scale a Vega spectrum # to the appropriate magnitude. Rescale to match the magnitude. # pysynphot.renorm() and pysynphot.setMagnitude are all broken. star = pysynphot.Vega.renorm(mag, 'vegamag', filt) # erg cm^2 s^-1 A^-1 # Observe the star and background through a filter and resample # at the IFU spectral sampling. star_obs = observation.Observation(star, filt, binset=ifu_wave) bkg_obs = observation.Observation(earth_bkg, filt, binset=ifu_wave, force="extrap") vega = pysynphot.FileSpectrum(pysynphot.locations.VegaFile) vega_obs = observation.Observation(vega, filt, binset=ifu_wave) # Propogate the star flux and background through the # atmosphere and telescope. star_obs *= earth_trans # erg s^-1 A^-1 cm^-2 star_obs *= tel_area * sys_throughput # erg s^-1 A^-1 vega_obs *= earth_trans # erg s^-1 A^-1 cm^-2 vega_obs *= tel_area * sys_throughput # erg s^-1 A^-1 bkg_obs *= tel_area * sys_throughput # erg s^-1 A^-1 arcsec^-2 # Convert them into photlam star_obs.convert('photlam') # photon s^-1 A^-1 vega_obs.convert('photlam') bkg_obs.convert('photlam') # photon s^-1 A^-1 arcsec^-2 # Pull the arrays out of the Observation objects star_counts = star_obs.binflux bkg_counts = bkg_obs.binflux vega_counts = vega_obs.binflux # Integrate each spectral channel using the ifu_wave (dlamda defined above). star_counts *= dlamda # photon s^-1 bkg_counts *= dlamda # photon s^-1 arcsec^-2 vega_counts *= dlamda # photon s^-1 NO? arcsec^-2 # Integrate over the aperture for the background and make # an aperture correction for the star. if seeing_limited: ee = get_seeing_ee(filt_name, sq_aper_diam) else: ee = get_roboAO_ee(mag, filt_name, sq_aper_diam) aper_area = sq_aper_diam**2 # square star_counts *= ee # photon s^-1 # TODO... Don't I need to do this for vega as well? # vega_counts *= ee bkg_counts *= aper_area # photon s^-1 arcsec^-2 pix_scale = 0.150 # arcsec per pixel if seeing_limited: pix_scale = 0.400 npix = (aper_area / pix_scale**2) npix *= npix_spec vega_mag = 0.03 star_mag = -2.5 * math.log10(star_counts.sum() / vega_counts.sum()) + vega_mag bkg_mag = -2.5 * math.log10(bkg_counts.sum() / vega_counts.sum()) + vega_mag signal = star_counts * tint # photon bkg = bkg_counts * tint # photon noise_variance = signal.copy() noise_variance += bkg noise_variance += read_noise**2 * npix noise_variance += dark_current * tint * npix noise = noise_variance**0.5 snr_spec = signal / noise # Calculate average signal-to-noise per spectral channel avg_signal = signal.sum() avg_noise = noise.sum() avg_snr = avg_signal / avg_noise msg = 'filt = {0:s} signal = {1:13.1f} bkg = {2:9.1f} SNR = {3:7.1f}' print msg.format(filt_name, avg_signal, bkg.mean(), avg_snr) # Inter-OH gives an overal reduction in background of # 2.3 mag at H - probably slightly less than this because this was with NIRSPEC # 2.0 mag at J # Do R=100 # Do R=30 return avg_snr, star_mag, bkg_mag, ifu_wave, signal, bkg, snr_spec