def fit_visit_spectra_single_star_model(norm_spectra, spec_errs, NN_coeffs_norm, NN_coeffs_flux, v_helios, p0, num_p0=1): ''' fit a set of visit spectra for a single object simultaneously with a single-star model, with the restriction that the velocity be the same at each epoch. v_helios is a guess of the heliocentric velocity at each visit, taken from the allStar catalog. p0 is a starting guess for the optimizer, typically obtained from fitting the combined spectrum ''' tol = 5e-4 # tolerance for when the optimizer should stop optimizing. stitched_spec, stitched_errs = np.concatenate( norm_spectra), np.concatenate(spec_errs) def fit_func(dummy_variable, *labels): stitched_model = spectral_model.single_star_model_visit_spectra( labels=labels, spec_errs=spec_errs, NN_coeffs_norm=NN_coeffs_norm, NN_coeffs_flux=NN_coeffs_flux) return stitched_model lower = np.array([4200, 4.0, -1, -0.3, 0, -100 + np.median(v_helios)]) upper = np.array([7000, 5.0, 0.5, 0.5, 45, 100 + np.median(v_helios)]) bounds = [lower, upper] # coming from the combined fit, the velocity label in p0 will be relative the # rest frame assumed in making the combined spectrum. p00 = np.copy(p0) p00[5] += np.median(v_helios) # if we want to initialize many walkers in different parts of parameter space, do so now. all_x0 = generate_starting_guesses_to_initialze_optimizers( p0=p00, bounds=bounds, num_p0=num_p0, vrange=(np.max(v_helios) - np.min(v_helios)) / 2, model='single_star') # run the optimizer popt, pcov, model_spec = fit_all_p0s(fit_func=fit_func, norm_spec=stitched_spec, spec_err=stitched_errs, all_x0=all_x0, bounds=bounds, tol=tol) model_specs = utils.unstitch_model_spectra(model_spec=model_spec, wavelength=wavelength) return popt, pcov, model_specs
def fit_visit_spectra_sb1_model(norm_spectra, spec_errs, NN_coeffs_norm, NN_coeffs_flux, v_helios, p0, num_p0=5): ''' fit a set of visit spectra for a single object simultaneously with an sb1 model. I.e., the same single-star spectral model makes the spectrum at each visit, but allow the heliocentric velocity to vary between visits. v_helios is a guess of the heliocentric velocity at each visit, taken from the allStar catalog. p0 is a starting guess for the optimizer, typically obtained from fitting the combined spectrum ''' tol = 5e-4 # tolerance for when the optimizer should stop optimizing. stitched_spec, stitched_errs = np.concatenate( norm_spectra), np.concatenate(spec_errs) def fit_func(dummy_variable, *labels): stitched_model = spectral_model.sb1_model_visit_spectra( labels=labels, spec_errs=spec_errs, NN_coeffs_norm=NN_coeffs_norm, NN_coeffs_flux=NN_coeffs_flux) return stitched_model v_min, v_max = np.min(v_helios), np.max(v_helios) lower = np.concatenate([[4200, 4.0, -1, -0.3, 0], len(v_helios) * [-100 + v_min]]) upper = np.concatenate([[7000, 5.0, 0.5, 0.5, 45], len(v_helios) * [100 + v_max]]) bounds = [lower, upper] p00 = np.concatenate([p0[:5], v_helios]) all_x0 = generate_starting_guesses_to_initialze_optimizers( p0=p00, bounds=bounds, num_p0=num_p0, vrange=(v_max - v_min) / 2, model='sb1') popt, pcov, model_spec = fit_all_p0s(fit_func=fit_func, norm_spec=stitched_spec, spec_err=stitched_errs, all_x0=all_x0, bounds=bounds, tol=tol) model_specs = utils.unstitch_model_spectra(model_spec=model_spec, wavelength=wavelength) return popt, pcov, model_specs
def fit_visit_spectra_sb2_model(norm_spectra, spec_errs, NN_coeffs_norm, NN_coeffs_flux, NN_coeffs_R, NN_coeffs_Teff2_logg2, v_helios, p0_combined, num_p0=5): ''' fit a set of visit spectra for a single target simultaneously with an sb2 model. This requires the velocities of the two stars to follow conservation of momentum; i.e., to fall on a line with negative slope when plotted against each other. v_helios is a guess of the heliocentric velocity at each visit, taken from the allStar catalog. p0_combined is a starting guess for the optimizer. It's expected to be in the format returned from fitting a binary model to a *combined* spectrum, i.e., p0_combined = [Teff1, logg1, [Fe/H], [Mg/Fe], q, vmacro1, vmacro2, dv1, dv2] ''' tol = 5e-4 # tolerance for when the optimizer should stop optimizing. stitched_spec, stitched_errs = np.concatenate( norm_spectra), np.concatenate(spec_errs) def fit_func(dummy_variable, *labels): stitched_model = spectral_model.sb2_model_visit_spectra( labels=labels, spec_errs=spec_errs, NN_coeffs_norm=NN_coeffs_norm, NN_coeffs_flux=NN_coeffs_flux, NN_coeffs_R=NN_coeffs_R, NN_coeffs_Teff2_logg2=NN_coeffs_Teff2_logg2) return stitched_model v_med, v_min, v_max = np.median(v_helios), np.min(v_helios), np.max( v_helios) sb2_p0 = np.concatenate( [p0_combined[:7], [p0_combined[4]], [v_med], v_helios]) teff1, logg1, feh, alphafe = p0_combined[:4] min_q = get_minimum_q_for_this_teff( Teff1=teff1, logg1=logg1, feh=feh, NN_coeffs_Teff2_logg2=NN_coeffs_Teff2_logg2) lower = np.concatenate( [[4200, 4.0, -1, -0.3, min_q, 0, 0, 0.2, -100 + v_med], len(v_helios) * [-100 + v_min]]) upper = np.concatenate([[7000, 5.0, 0.5, 0.5, 1, 45, 45, 1.5, 100 + v_med], len(v_helios) * [100 + v_max]]) bounds = [lower, upper] all_x0 = generate_starting_guesses_to_initialze_optimizers( p0=sb2_p0, bounds=bounds, num_p0=num_p0, vrange=(v_max - v_min) / 2, model='sb2') popt, pcov, model_spec = fit_all_p0s(fit_func=fit_func, norm_spec=stitched_spec, spec_err=stitched_errs, all_x0=all_x0, bounds=bounds, tol=tol) model_specs = utils.unstitch_model_spectra(model_spec=model_spec, wavelength=wavelength) return popt, pcov, model_specs
def fit_visit_spectra_N(norm_spectra, spec_errs, NN_coeffs_norm, NN_coeffs_flux, NN_coeffs_Teff2_logg2, NN_coeffs_R, v_helios, p0_single, num_p0=10, N=3, fix_vmac=0, vmac=6): ''' fit a set of visit spectra for a single object simultaneously, N components v_helios is a guess of the heliocentric velocity at each visit, taken from the allStar catalog. p0 is a starting guess for the optimizer, typically obtained from fitting the combined spectrum labels = [Teff, logg, [Fe/H], [Mg/Fe], vmacro1, dv1] + [q2, vmacro2, dv2] + .. [qN, vmacroN, dvN] ## then below is new + [RV1_v2, RV2_v2.. RVN_v2] + ... + [RV1_vN, RV2_vN.. RVN_vN] len(labels)=6+3(N-1)+N*(Nv-1) ''' tol = 5e-4 # tolerance for when the optimizer should stop optimizing. stitched_spec, stitched_errs = np.concatenate( norm_spectra), np.concatenate(spec_errs) Nv = len(spec_errs) def fit_func(dummy_variable, *labels): #print ('test') #print (labels) stitched_model = spectral_model.sbN_model_visit_spectra( labels=labels, spec_errs=spec_errs, NN_coeffs_norm=NN_coeffs_norm, NN_coeffs_flux=NN_coeffs_flux, NN_coeffs_Teff2_logg2=NN_coeffs_Teff2_logg2, NN_coeffs_R=NN_coeffs_R) return stitched_model teff1, logg1, feh, alphafe, vmacro1, dv1 = p0_single # a cluster where all stars are identical (should have a spectrum identical to # that of the primary only) p0 = [teff1, logg1, feh, alphafe, vmacro1, dv1 ] + [1, vmacro1, dv1] * (N - 1) + [ dv1, ] * N * (Nv - 1) min_q = 0 #get_minimum_q_for_this_teff(Teff1 = teff1, logg1 = logg1, feh = feh, #NN_coeffs_Teff2_logg2 = NN_coeffs_Teff2_logg2) # print ('JL note: min_q=',min_q) v_min, v_max = np.min(v_helios), np.max(v_helios) lower = [3000, 0.0, -1, -0.3, 0, -100 ] + [min_q, 0, -100 + v_min] * (N - 1) + [ -100 + v_min, ] * N * (Nv - 1) upper = [7200, 5.0, 0.5, 0.5, 45, 100] + [1, 45, 100 + v_max] * (N - 1) + [ 100 + v_max, ] * N * (Nv - 1) #lower = np.concatenate([[3000, 0.0, -1, -0.3, 0], len(v_helios) * [-100 + v_min]]) #upper = np.concatenate([[7200, 5.0, 0.5, 0.5, 45], len(v_helios) * [100 + v_max]]) bounds = [lower, upper] #p00 = np.concatenate([p0[:5], v_helios]) ##### initial walkers all_x0 = generate_starting_guesses_to_initialze_optimizers( p0=p0, bounds=bounds, num_p0=num_p0, model='sbN', Nv=Nv, N=N) ##vrange = (v_max - v_min)/2 popt, pcov, model_spec = fit_all_p0s(fit_func=fit_func, norm_spec=stitched_spec, spec_err=stitched_errs, all_x0=all_x0, bounds=bounds, tol=tol) model_specs = utils.unstitch_model_spectra(model_spec=model_spec, wavelength=wavelength) return popt, pcov, model_specs