def nebular(self, params, outwave): """If the emission_rest_wavelengths parameter is present, return a nebular emission line spectrum. Currently uses several approximations for the velocity broadening. Currently does *not* affect photometry. Only provides samples of the nebular spectrum at outwave, so will not be correct for total power unless outwave densley samples the emission dispersion. :returns nebspec: The nebular emission in the observed frame, at the wavelengths specified by the obs['wavelength']. """ if 'emission_rest_wavelengths' not in params: return 0. mu = vac2air(params['emission_rest_wavelengths']) # try to get a nebular redshift, otherwise use stellar redshift, # otherwise use no redshift a1 = params.get('zred_emission', self.params.get('zred', 0.0)) + 1.0 A = params.get('emission_luminosity', 0.) sigma = params.get('emission_disp', 10.) if params.get('smooth_velocity', False): # This is an approximation to get the dispersion in terms of # wavelength at the central line wavelength, but should work much # of the time sigma = mu * sigma / 2.998e5 return gauss(outwave, mu * a1, A, sigma * a1)
def load_obs(objname=None, noisefactor=1.0, calibrated=False, mask=True, broaden_obs=False, wlo=3750., whi=7500., **extras): assert objname == 'M67' bmag = 7.5 #hack obs = {} dat = np.loadtxt(os.path.join(sdir, 'data/m67_nobs.dat')) obs['wavelength'] = observate.vac2air(dat[:, 0]) obs['spectrum'] = dat[:, 1] obs['unc'] = dat[:, 2] obs['filters'] = observate.load_filters(['sdss_g0']) obs['maggies'] = np.array([10**(-0.4 * bmag)]) obs['maggies_unc'] = 0.05 * obs['maggies'] # mask obs['mask'] = (obs['wavelength'] > wlo) & (obs['wavelength'] < whi) #adjust uncertainties obs['unc'] *= noisefactor obs['noisefactor'] = noisefactor obs['spec_calibrated'] = calibrated return obs
def process_component(self, i, outwave, filters): """Basically do all the COMPSP stuff for one component. """ cspec = self.basis_spec[i, :].copy() cphot = 0 inwave = self.ssp.wavelengths if self.safe: cspec = np.interp(self.params['outwave'], vac2air(inwave), cspec / a) cphot = 10**(-0.4 * getSED(inwave, cspec / a, filters)) return cspec, cphot # Dust attenuation tage = self.params['tage'][i] tesc = self.params.get('dust_tesc', 0.01) dust1 = self.params.get('dust1', 0.0) dust2 = self.params['dust2'] a = (1 + self.params.get('zred', 0.0)) dust = (tage < tesc) * dust1 + dust2 att = self.params['dust_curve'][0](inwave, **self.params) cspec *= np.exp(-att * dust) if filters is not None: cphot = 10**(-0.4 * getSED(inwave * a, cspec / a, filters)) # Wavelength scale. Broadening and redshifting and placing on output # wavelength grid if self.params.get('lsf', [None])[0] is not None: cspec = smoothspec( vac2air(inwave) * a, cspec / a, self.params['sigma_smooth'], **self.params) else: sigma = self.params.get('sigma_smooth', 0.0) cspec = self.ssp.smoothspec(inwave, cspec, sigma) cspec = np.interp(self.params['outwave'], vac2air(inwave * a), cspec / a) return cspec, cphot
def process_component(self, i, outwave, filters): """Basically do all the COMPSP stuff for one component. """ cspec = self.basis_spec[i, :].copy() cphot = 0 inwave = self.ssp.wavelengths if self.safe: cspec = np.interp(self.params['outwave'], vac2air(inwave), cspec/a) cphot = 10**(-0.4 * getSED(inwave, cspec/a, filters)) return cspec, cphot # Dust attenuation tage = self.params['tage'][i] tesc = self.params.get('dust_tesc', 0.01) dust1 = self.params.get('dust1', 0.0) dust2 = self.params['dust2'] a = (1 + self.params.get('zred', 0.0)) dust = (tage < tesc) * dust1 + dust2 att = self.params['dust_curve'][0](inwave, **self.params) cspec *= np.exp(-att*dust) if filters is not None: cphot = 10**(-0.4 * getSED(inwave*a, cspec / a, filters)) # Wavelength scale. Broadening and redshifting and placing on output # wavelength grid if self.params.get('lsf', [None])[0] is not None: cspec = smoothspec(vac2air(inwave) * a, cspec / a, self.params['sigma_smooth'], **self.params) else: sigma = self.params.get('sigma_smooth', 0.0) cspec = self.ssp.smoothspec(inwave, cspec, sigma) cspec = np.interp(self.params['outwave'], vac2air(inwave * a), cspec/a) return cspec, cphot
def load_obs(objname=None, noisefactor=1.0, calibrated=False, mask=True, broaden_obs=False, wlo=3750., whi=7500., **extras): assert objname == 'M67' bmag = 7.5 # hack obs = {} dat = np.loadtxt(os.path.join(sdir, 'data/m67_nobs.dat')) obs['wavelength'] = observate.vac2air(dat[:, 0]) obs['spectrum'] = dat[:, 1] obs['unc'] = dat[:, 2] obs['filters'] = observate.load_filters(['sdss_g0']) obs['maggies'] = np.array([10**(-0.4 * bmag)]) obs['maggies_unc'] = 0.05 * obs['maggies'] # mask obs['mask'] = (obs['wavelength'] > wlo) & (obs['wavelength'] < whi) #adjust uncertainties obs['unc'] *= noisefactor obs['noisefactor'] = noisefactor obs['spec_calibrated'] = calibrated return obs
def get_spectrum(self, outwave=None, filters=None, peraa=False, **kwargs): """Return an attenuated, smoothed, distance dimmed stellar spectrum and SED. :returns spec: The spectrum on the outwave grid (assumed in air), in AB maggies. If peraa is True then the spectrum is erg/s/cm^2/AA. :returns phot: Observed frame photometry in units of AB maggies. If ``lumdist`` is not present in the parameters then these are absolute maggies, otherwise they are apparent. :returns x: A blob of extra quantities (e.g. mass, uncertainty) """ self.update(**kwargs) # star spectrum (in Lsun/Hz) wave, spec, unc = self.get_star_spectrum(**self.params) spec *= self.normalize() # dust if 'dust_curve' in self.params: att = self.params['dust_curve'](self._wave, **self.params) spec *= np.exp(-att) # Redshifting + Wavelength solution. We also convert to in-air. a = 1 + self.params.get('zred', 0) b = 0.0 if 'wavecal_coeffs' in self.params: x = wave - wave.min() x = 2.0 * (x / x.max()) - 1.0 c = np.insert(self.params['wavecal_coeffs'], 0, 0) # assume coeeficients give shifts in km/s b = chebval(x, c) / (lightspeed*1e-13) wa, sa = vac2air(wave) * (a + b), spec * a if outwave is None: outwave = wa # Broadening, interpolation onto output wavelength grid if 'sigma_smooth' in self.params: smspec = self.smoothspec(wa, sa, self.params['sigma_smooth'], outwave=outwave, **self.params) elif outwave is not wa: smspec = np.interp(outwave, wa, sa, left=0, right=0) else: smspec = sa # Photometry (observed frame absolute maggies) if filters is not None: mags = getSED(wa, sa * lightspeed / wa**2 * to_cgs, filters) phot = np.atleast_1d(10**(-0.4 * mags)) else: phot = 0.0 # Distance dimming. Default to 10pc distance (i.e. absolute) dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2 if peraa: # spectrum will be in erg/s/cm^2/AA smspec *= to_cgs / dfactor * lightspeed / outwave**2 else: # Spectrum will be in maggies smspec *= to_cgs / dfactor / 1e3 / (3631*jansky_mks) # Convert from absolute maggies to apparent maggies phot /= dfactor return smspec, phot, None