def redden(flux, wave=None, photbands=None, ebv=0., rtype='flux', law='cardelli1989', **kwargs): """ Redden flux or magnitudes The reddening parameters C{ebv} means E(B-V). If it is negative, we B{deredden}. If you give the keyword C{wave}, it is assumed that you want to (de)redden a B{model}, i.e. a spectral energy distribution. If you give the keyword C{photbands}, it is assumed that you want to (de)redden B{photometry}, i.e. integrated fluxes. @param flux: fluxes to (de)redden (magnitudes if C{rtype='mag'}) @type flux: ndarray (floats) @param wave: wavelengths matching the fluxes (or give C{photbands}) @type wave: ndarray (floats) @param photbands: photometry bands matching the fluxes (or give C{wave}) @type photbands: ndarray of str @param ebv: reddening parameter E(B-V) @type ebv: float @param rtype: type of dereddening (magnituds or fluxes) @type rtype: str ('flux' or 'mag') @return: (de)reddened flux/magnitude @rtype: ndarray (floats) """ if photbands is not None: wave = filters.get_info(photbands)['eff_wave'] old_settings = np.seterr(all='ignore') wave, reddeningMagnitude = get_law(law, wave=wave, **kwargs) if rtype == 'flux': # In this case flux means really flux flux_reddened = flux / 10**(reddeningMagnitude * ebv / 2.5) np.seterr(**old_settings) return flux_reddened elif rtype == 'mag': # In this case flux means actually a magnitude magnitude = flux magnitude_reddened = magnitude + reddeningMagnitude * ebv np.seterr(**old_settings) return magnitude_reddened
def redden(flux,wave=None,photbands=None,ebv=0.,rtype='flux',law='cardelli1989',**kwargs): """ Redden flux or magnitudes The reddening parameters C{ebv} means E(B-V). If it is negative, we B{deredden}. If you give the keyword C{wave}, it is assumed that you want to (de)redden a B{model}, i.e. a spectral energy distribution. If you give the keyword C{photbands}, it is assumed that you want to (de)redden B{photometry}, i.e. integrated fluxes. @param flux: fluxes to (de)redden (magnitudes if C{rtype='mag'}) @type flux: ndarray (floats) @param wave: wavelengths matching the fluxes (or give C{photbands}) @type wave: ndarray (floats) @param photbands: photometry bands matching the fluxes (or give C{wave}) @type photbands: ndarray of str @param ebv: reddening parameter E(B-V) @type ebv: float @param rtype: type of dereddening (magnituds or fluxes) @type rtype: str ('flux' or 'mag') @return: (de)reddened flux/magnitude @rtype: ndarray (floats) """ if photbands is not None: wave = filters.get_info(photbands)['eff_wave'] old_settings = np.seterr(all='ignore') wave, reddeningMagnitude = get_law(law,wave=wave,**kwargs) if rtype=='flux': # In this case flux means really flux flux_reddened = flux / 10**(reddeningMagnitude*ebv/2.5) np.seterr(**old_settings) return flux_reddened elif rtype=='mag': # In this case flux means actually a magnitude magnitude = flux magnitude_reddened = magnitude + reddeningMagnitude*ebv np.seterr(**old_settings) return magnitude_reddened
def get_law(name,norm='E(B-V)',wave_units='AA',photbands=None,**kwargs): """ Retrieve an interstellar reddening law. Parameter C{name} must be the function name of one of the laws defined in this module. By default, the law will be interpolated on a grid from 100 angstrom to 10 micron in steps of 10 angstrom. This can be adjusted with the parameter C{wave} (array), which B{must} be in angstrom. You can change the units ouf the returned wavelength array via C{wave_units}. By default, the curve is normalised with respect to E(B-V) (you get A(l)/E(B-V)). You can set the C{norm} keyword to Av if you want A(l)/Av. Remember that A(V) = Rv * E(B-V) The parameter C{Rv} is by default 3.1, other reasonable values lie between 2.0 and 5.1 Extra accepted keywords depend on the type of reddening law used. Example usage: >>> wave = np.r_[1e3:1e5:10] >>> wave,mag = get_law('cardelli1989',wave=wave,Rv=3.1) @param name: name of the interstellar law @type name: str, one of the functions defined here @param norm: type of normalisation of the curve @type norm: str (one of E(B-V), Av) @param wave_units: wavelength units @type wave_units: str (interpretable for units.conversions.convert) @param photbands: list of photometric passbands @type photbands: list of strings @keyword wave: wavelength array to interpolate the law on @type wave: ndarray @return: wavelength, reddening magnitude @rtype: (ndarray,ndarray) """ #-- get the inputs wave_ = kwargs.pop('wave',None) Rv = kwargs.setdefault('Rv',3.1) #-- get the curve wave,mag = globals()[name.lower()](**kwargs) wave_orig,mag_orig = wave.copy(),mag.copy() #-- interpolate on user defined grid if wave_ is not None: if wave_units != 'AA': wave_ = conversions.convert(wave_units,'AA',wave_) mag = np.interp(wave_,wave,mag,right=0) wave = wave_ #-- pick right normalisation: convert to A(lambda)/Av if needed if norm.lower()=='e(b-v)': mag *= Rv else: #-- we allow ak and av as shortcuts for normalisation in JOHNSON K and # V bands if norm.lower()=='ak': norm = 'JOHNSON.K' elif norm.lower()=='av': norm = 'JOHNSON.V' norm_reddening = model.synthetic_flux(wave_orig,mag_orig,[norm])[0] logger.info('Normalisation via %s: Av/%s = %.6g'%(norm,norm,1./norm_reddening)) mag /= norm_reddening #-- maybe we want the curve in photometric filters if photbands is not None: mag = model.synthetic_flux(wave,mag,photbands) wave = filters.get_info(photbands)['eff_wave'] #-- set the units of the wavelengths if wave_units != 'AA': wave = conversions.convert('AA',wave_units,wave) return wave,mag
def get_law(name, norm='E(B-V)', wave_units='AA', photbands=None, **kwargs): """ Retrieve an interstellar reddening law. Parameter C{name} must be the function name of one of the laws defined in this module. By default, the law will be interpolated on a grid from 100 angstrom to 10 micron in steps of 10 angstrom. This can be adjusted with the parameter C{wave} (array), which B{must} be in angstrom. You can change the units ouf the returned wavelength array via C{wave_units}. By default, the curve is normalised with respect to E(B-V) (you get A(l)/E(B-V)). You can set the C{norm} keyword to Av if you want A(l)/Av. Remember that A(V) = Rv * E(B-V) The parameter C{Rv} is by default 3.1, other reasonable values lie between 2.0 and 5.1 Extra accepted keywords depend on the type of reddening law used. Example usage: >>> wave = np.r_[1e3:1e5:10] >>> wave,mag = get_law('cardelli1989',wave=wave,Rv=3.1) @param name: name of the interstellar law @type name: str, one of the functions defined here @param norm: type of normalisation of the curve @type norm: str (one of E(B-V), Av) @param wave_units: wavelength units @type wave_units: str (interpretable for units.conversions.convert) @param photbands: list of photometric passbands @type photbands: list of strings @keyword wave: wavelength array to interpolate the law on @type wave: ndarray @return: wavelength, reddening magnitude @rtype: (ndarray,ndarray) """ #-- get the inputs wave_ = kwargs.pop('wave', None) Rv = kwargs.setdefault('Rv', 3.1) #-- get the curve wave, mag = globals()[name.lower()](**kwargs) wave_orig, mag_orig = wave.copy(), mag.copy() #-- interpolate on user defined grid if wave_ is not None: if wave_units != 'AA': wave_ = conversions.convert(wave_units, 'AA', wave_) mag = np.interp(wave_, wave, mag, right=0) wave = wave_ #-- pick right normalisation: convert to A(lambda)/Av if needed if norm.lower() == 'e(b-v)': mag *= Rv else: #-- we allow ak and av as shortcuts for normalisation in JOHNSON K and # V bands if norm.lower() == 'ak': norm = 'JOHNSON.K' elif norm.lower() == 'av': norm = 'JOHNSON.V' norm_reddening = model.synthetic_flux(wave_orig, mag_orig, [norm])[0] logger.info('Normalisation via %s: Av/%s = %.6g' % (norm, norm, 1. / norm_reddening)) mag /= norm_reddening #-- maybe we want the curve in photometric filters if photbands is not None: mag = model.synthetic_flux(wave, mag, photbands) wave = filters.get_info(photbands)['eff_wave'] #-- set the units of the wavelengths if wave_units != 'AA' and photbands is not None: wave = conversions.convert('AA', wave_units, wave) return wave, mag