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
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 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
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)
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')
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)
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'))
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
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')
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
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'))
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)
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}
def use(self): spec = pys.ArraySpectrum(wave=self._wave, flux=self._flux, waveunits=self._wunit, fluxunits=self._funit) return spec
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)
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
+ 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]
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
def testsp(self): self.sp = S.ArraySpectrum(self.wv, self.fl, fluxunits='photlam') tst = self.sp(1500) self.assertTrue(tst == 10)
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
def setUp(self): self.sp=S.ArraySpectrum(N.arange(1,10000), N.arange(9999)*2.5)