def real_spec(request): band = request.param wav, flux = load_aces_spectrum([3900, 4.5, 0.0, 0]) wav, flux = wav_selector(wav, flux, *band_limits(band)) flux = flux / snr_constant_band(wav, flux, 100, band) atm = Atmosphere.from_band(band).at(wav) return wav, flux, atm.transmission
def test_wav_selector(x, y, wav_min, wav_max): """Test some properties of wavelength selector.""" y = [xi + y for xi in x] # just to make y different x1, y1 = utils.wav_selector(x, y, wav_min, wav_max) assert all(x1 >= wav_min) assert all(x1 <= wav_max) assert len(x1) == len(y1) assert isinstance(x1, np.ndarray) assert isinstance(y1, np.ndarray)
def convolution( wav: ndarray, flux: ndarray, vsini: float, R: float, band: str = "All", *, epsilon: float = 0.6, fwhm_lim: float = 5.0, num_procs: Optional[int] = None, normalize: bool = True, ): """Perform convolution of spectrum. Rotational convolution followed by a Gaussian of a specified resolution R. Parameters ---------- wav: ndarray Wavelength in microns flux: ndarray Photon flux vsini: float Rotational velocity in km/s. R: int Resolution of instrumental profile. band: str Wavelength band to choose, default="All" epsilon: float (default = 0.6) Limb darkening coefficient fwhm_lim: float (default = 5.0) FWHM limit for instrument broadening. normalize: bool (default = True) Area normalize the broadening kernels (corrects for unequal sampling of position). num_procs: int, None Number of processes to use with multiprocess. If None it is assigned to 1 less then total number of cores. If num_procs = 0, then multiprocess is not used. Returns ------- wav_band: ndarray Wavelength for the selected band. flux_band: ndarray Original flux for the selected band. flux_conv: ndarray Convolved flux for the selected band. """ wav_band, flux_band = band_selector(wav, flux, band) # We need to calculate the fwhm at this value in order to set the starting point for the convolution fwhm_min = wav_band[0] / R # fwhm at the extremes of vector fwhm_max = wav_band[-1] / R # performing convolution with rotation kernel print( "Starting the Rotation convolution for vsini={0:.2f}...".format(vsini)) delta_lambda_min = wav_band[0] * vsini / c_kmps delta_lambda_max = wav_band[-1] * vsini / c_kmps # widest wavelength bin for the rotation convolution lower_lim = wav_band[0] - delta_lambda_min - fwhm_lim * fwhm_min upper_lim = wav_band[-1] + delta_lambda_max + fwhm_lim * fwhm_max wav_ext_rotation, flux_ext_rotation = wav_selector(wav, flux, lower_lim, upper_lim) # wide wavelength bin for the resolution_convolution lower_lim = wav_band[0] - fwhm_lim * fwhm_min upper_lim = wav_band[-1] + fwhm_lim * fwhm_max extended_wav, __ = wav_selector(wav, flux, lower_lim, upper_lim) # rotational convolution flux_conv_rot = rotational_convolution( extended_wav, wav_ext_rotation, flux_ext_rotation, vsini, epsilon=epsilon, num_procs=num_procs, normalize=normalize, ) print("Starting the Resolution convolution...") flux_conv_res = resolution_convolution( wav_band, extended_wav, flux_conv_rot, R, fwhm_lim=fwhm_lim, num_procs=num_procs, normalize=normalize, ) return wav_band, flux_band, flux_conv_res
def convolution( wav: ndarray, flux: ndarray, vsini: float, R: float, band: str = "All", *, epsilon: float = 0.6, fwhm_lim: float = 5.0, num_procs: Optional[Union[int, joblib.parallel.Parallel]] = None, normalize: bool = True, verbose: bool = True, ): r"""Perform rotational then Instrumental broadening with convolutions. Parameters ---------- wav: ndarray Wavelength array. flux: ndarray Flux array. vsini: float Rotational velocity in km/s. R: int Resolution of instrumental profile. band: str Wavelength band to choose, default is "All". epsilon: float Limb darkening coefficient. Default is 0.6. fwhm_lim: float FWHM limit for instrument broadening. Default is 5.0. normalize: bool Area normalize the broadening kernel. This corrects for kernel area with unequal wavelength spacing. Default is True. num_procs: int, None or joblib.parallel.Parallel. Number of processes to use, n_job parameter in joblib. If num_procs = 1, then a single core is used. Can also be a joblib.parallel.Parallel instance. verbose: bool Show the tqdm progress bar. Default is True. Returns ------- wav_band: ndarray Wavelength for the selected band. flux_band: ndarray Original flux for the selected band. flux_conv: ndarray Convolved flux for the selected band. """ wav_band, flux_band = band_selector(wav, flux, band) # Calculate FWHM at each end for the convolution fwhm_min = wav_band[0] / R # fwhm at the extremes of vector fwhm_max = wav_band[-1] / R # performing convolution with rotation kernel if verbose: print("Starting the Rotation convolution for vsini={0:.2f}...".format( vsini)) delta_lambda_min = wav_band[0] * vsini / c_kmps delta_lambda_max = wav_band[-1] * vsini / c_kmps # widest wavelength bin for the rotation convolution lower_lim = wav_band[0] - delta_lambda_min - fwhm_lim * fwhm_min upper_lim = wav_band[-1] + delta_lambda_max + fwhm_lim * fwhm_max wav_ext_rotation, flux_ext_rotation = wav_selector(wav, flux, lower_lim, upper_lim) # wide wavelength bin for the resolution_convolution lower_lim = wav_band[0] - fwhm_lim * fwhm_min upper_lim = wav_band[-1] + fwhm_lim * fwhm_max extended_wav, __ = wav_selector(wav, flux, lower_lim, upper_lim) # rotational convolution flux_conv_rot = rotational_convolution( extended_wav, wav_ext_rotation, flux_ext_rotation, vsini, epsilon=epsilon, num_procs=num_procs, normalize=normalize, verbose=verbose, ) if verbose: print("Starting the Resolution convolution...") flux_conv_res = resolution_convolution( wav_band, extended_wav, flux_conv_rot, R, fwhm_lim=fwhm_lim, num_procs=num_procs, normalize=normalize, verbose=verbose, ) return wav_band, flux_band, flux_conv_res