def test_pdwriter(): """Check pd_writer same write_col with with exponential flag.""" filedir = "data/test_data/obsolete/" data = np.random.randn(3, 100) * 1e7 pd2col_name = filedir + "pd2col_test.dat" pd3col_name = filedir + "pd3col_test.dat" twocol_name = filedir + "2col_test.dat" threecol_name = filedir + "3col_test.dat" # write files io.pdwrite_2col(pd2col_name, data[0], data[1]) io.pdwrite_3col(pd3col_name, data[0], data[1], data[2]) eniric.obsolete.IOmodule.write_e_2col(twocol_name, data[0], data[1]) eniric.obsolete.IOmodule.write_e_3col(threecol_name, data[0], data[1], data[2]) # re-read files a = io.pdread_2col(pd2col_name) b = io.pdread_2col(twocol_name) c = io.pdread_3col(pd3col_name) d = io.pdread_3col(threecol_name) # check results the same assert np.allclose(a[0], b[0]) assert np.allclose(a[1], b[1]) assert np.allclose(c[0], d[0]) assert np.allclose(c[1], d[1]) assert np.allclose(c[2], d[2]) # clean-up utils.silent_remove(pd2col_name) utils.silent_remove(pd3col_name) utils.silent_remove(twocol_name) utils.silent_remove(threecol_name)
def read_spectrum(spec_name: str) -> Tuple[ndarray, ndarray]: """Function that reads a flux spectra from the database!. If a energy flux spectra is read then it converts it to photons. Parameters ---------- spec_name: str Location and name of model spectrum file. Returns ------- wav: array-like, float Wavelength in microns. flux_photons: array-like, float Photon flux. """ if "_res" in spec_name or "_vsini" in spec_name: raise ValueError("Using wrong function to load resampled spectrum.") if "photon" in spec_name: wav_micron, flux_photons = io.pdread_2col(spec_name) else: wav, flux = io.pdread_2col(spec_name) wav_micron = wav * 1.0e-4 # Conversion to microns flux_photons = flux * wav_micron # Convert to photons return wav_micron, flux_photons
def test_pdread_2col(): """Test reading 2cols with pandas.""" spectrum_1 = "data/test_data/obsolete/Sample_input_phoenix.dat" spectrum_2 = "data/test_data/obsolete/Sample_resampled_spectrum_res3.dat" wav_1_pd, flux_1_pd = io.pdread_2col(spectrum_1) wav_1, flux_1 = eniric.obsolete.IOmodule.read_2col(spectrum_1) assert np.allclose(wav_1_pd, np.array(wav_1)) assert np.allclose(flux_1_pd, np.array(flux_1)) wav_2_pd, flux_2_pd = io.pdread_2col(spectrum_2, noheader=True) wav_2, flux_2 = eniric.obsolete.IOmodule.read_2col(spectrum_2) assert np.allclose(wav_2_pd, np.array(wav_2)) assert np.allclose(flux_2_pd, np.array(flux_2))
def compare_output(): """Function that compares a spectrum prior to convolution, after, and after resampling.""" pre_convolution = ( "PHOENIX_ACES_spectra/lte03900-4.50-0.0.PHOENIX-ACES-AGSS-COND-2011-HiRes_wave_CUT_nIR.dat" ) pre_wav, pre_flux = io.pdread_2col(pre_convolution) pre_wav = np.array(pre_wav, dtype=float) * 1.0e-4 # conversion to microns pre_flux = np.array(pre_flux, dtype=float) * pre_wav convolved = "results_new/Spectrum_M6-PHOENIX-ACES_Jband_vsini1.0_R100k.dat" sampled = "resampled_new/Spectrum_M6-PHOENIX-ACES_Jband_vsini1.0_R100k_res3.dat" conv_wav, theory_flux, conv_flux = io.pdread_3col(convolved) sampled_wav, sampled_flux = io.pdread_2col(sampled) theory_flux = np.array(theory_flux) conv_flux = np.array(conv_flux) ratio_flux = moving_average(conv_flux, 300) / moving_average(theory_flux, 300) ratio_flux = ratio_flux / ratio_flux[0] plt.figure(1) plt.xlabel(r"wavelength [$\mu$m])") plt.ylabel(r"Flux[ ] ") plt.plot(conv_wav, np.array(theory_flux) / theory_flux[0], color="k") plt.plot(conv_wav, np.array(conv_flux) / conv_flux[0], color="b") plt.plot(conv_wav, ratio_flux, color="g", linestyle="--") plt.show() plt.close() conv_flux_corrected = conv_flux / ratio_flux plt.figure(1) plt.xlabel(r"wavelength [$\mu$m])") plt.ylabel(r"Flux corrected[ ] ") plt.plot(conv_wav, np.array(theory_flux) / theory_flux[0], color="k") plt.plot( conv_wav, np.array(conv_flux_corrected) / conv_flux_corrected[0], color="b" ) plt.show() plt.close()
def resampled_data(request): """Load a resampled spectra. Returns id-string, wavelength and flux. Fixture so that data files only get loaded once here. """ star, band, vel, res = request.param id_string = "{0:s}-{1:s}-{2:.1f}-{3:s}".format(star, band, float(vel), res) test_data = os.path.join( eniric.paths["resampled"], resampled_template.format(star, band, vel, res) ) wav, flux = io.pdread_2col(test_data) return id_string, wav, flux
def test_band_snr_norm_test_data(): """Compared to wav snr norm.""" # snr_constant_band star, band, vel, res = "M0", "J", 1.0, "100k" test_data = os.path.join(eniric.paths["resampled"], resampled_template.format(star, band, vel, res)) wav, flux = io.pdread_2col(test_data) assert snrnorm.snr_constant_band( wav, flux, band="J", snr=100) == snrnorm.snr_constant_wav(wav, flux, wav_ref=1.25, snr=100) assert snrnorm.snr_constant_band(wav, flux, band="J", snr=100) != snrnorm.snr_constant_wav( wav, flux, wav_ref=1.24, snr=100)
def test_write_read_2col(tmpdir): """Check pd_writer same write_col with with exponential flag.""" data = np.random.randn(2, 100) * 1e7 tmp_file = tmpdir.join("file_col2.dat") tmp_file_name = str(tmp_file) # write files io.pdwrite_2col(tmp_file_name, data[0], data[1]) # re-read files a = io.pdread_2col(tmp_file_name) # check results the same assert np.allclose(a[0], data[0]) assert np.allclose(a[1], data[1]) # clean-up utils.silent_remove(tmp_file_name)
def get_reference_spectrum( id_string: str, ref_band: str = "J" ) -> Tuple[ndarray, ndarray]: """From the id_string find the correct Spectrum to calculate norm_constant from.""" # TODO: add option for Alpha into ID-String # TODO: Add metallicity and logg into id string # TODO: Add metallicity folder # Determine the correct reference file to use. if ("Alpha=" in id_string) or ("smpl" in id_string): raise NotImplementedError else: star, band, vel, res = decompose_id_string(id_string) smpl = 3.0 # Fixed value atm ref_band = ref_band.upper() if ref_band == "SELF": ref_band = band file_to_read = ( "Spectrum_{0}-PHOENIX-ACES_{1}band_vsini{2}_R{3}" "_res{4:3.01f}.dat" ).format(star, ref_band, vel, res, float(smpl)) try: wav_ref, flux_ref = pdread_2col( os.path.join(eniric.paths["resampled"], file_to_read) ) except FileNotFoundError as e: print( "The reference spectra in {0:s} band was not found for id {1:s}".format( ref_band, id_string ) ) raise e return wav_ref, flux_ref
def calculate_prec( spectral_types, bands, vsini, resolution, sampling, plot_atm=False, plot_ste=False, plot_flux=True, paper_plots=True, rv_offset=0.0, use_unshifted=False, snr=100, ref_band="J", new=True, grad=True, ): """Calculate precisions for given combinations. grad: bool Use more precise gradient function. """ # TODO: iterate over band last so that the J band normalization value can be # obtained first and applied to each band. print("using new config.yaml file here!!!!!!!!!!!!!!") results = {} # creating empty dictionary for the results wav_plot_m0 = [] # creating empty lists for the plots flux_plot_m0 = [] wav_plot_m3 = [] flux_plot_m3 = [] wav_plot_m6 = [] flux_plot_m6 = [] wav_plot_m9 = [] flux_plot_m9 = [] for band in bands: if use_unshifted: atmmodel = os.path.join( eniric.paths["atmmodel"], "{0}_{1}.dat".format(eniric.atmmodel["base"], band), ) print("Reading atmospheric model...") atm = Atmosphere.from_file(atmmodel) wav_atm, flux_atm, std_flux_atm, mask_atm = ( atm.wl, atm.transmission, atm.std, atm.mask, ) print( ( "There were {0:d} unmasked pixels out of {1:d}., or {2:.1%}." "" ).format( np.sum(mask_atm), len(mask_atm), np.sum(mask_atm) / len(mask_atm) ) ) print( "The model ranges from {0:4.2f} to {1:4.2f} micron.".format( wav_atm[0], wav_atm[-1] ) ) print("Done.") print("Calculating impact of Barycentric movement on mask...") # mask_atm = atm.old_barycenter_shift(wav_atm, mask_atm, rv_offset=rv_offset) mask_atm = barycenter_shift(wav_atm, mask_atm, rv_offset=rv_offset) else: shifted_atmmodel = os.path.join( eniric.paths["atmmodel"], "{0}_{1}_bary.dat".format(eniric.atmmodel["base"], band), ) print("Reading pre-doppler-shifted atmospheric model...") atm = Atmosphere.from_file(shifted_atmmodel) wav_atm, flux_atm, std_flux_atm, mask_atm = ( atm.wl, atm.transmission, atm.std, atm.mask, ) print("Done.") print( ("There were {0:d} unmasked pixels out of {1:d}, or {2:.1%}." "").format( np.sum(mask_atm), len(mask_atm), np.sum(mask_atm) / len(mask_atm) ) ) if plot_atm: # moved plotting code to separate code, eniric.obsolete.plotting_functions.py plt_functions.plot_atmosphere_model(wav_atm, flux_atm, mask_atm) # theoretical ratios calculation # wav_m0, flux_m0, wav_m3, flux_m3, wav_m6, flux_m6, wav_m9, flux_m9 = read_nIRspectra() iterations = itertools.product(spectral_types, vsini, resolution, sampling) # for star in spectral_types: # for vel in vsini: # for res in resolution: # for smpl in sampling: for (star, vel, res, smpl) in iterations: file_to_read = ( "Spectrum_{0}-PHOENIX-ACES_{1}band_vsini{2}_R{3}" "_res{4:2.01f}.dat" ).format(star, band, vel, res, float(smpl)) # print("Working on "+file_to_read+".") try: wav_stellar, flux_stellar = io.pdread_2col( os.path.join(eniric.paths["resampled"], file_to_read) ) except FileNotFoundError: # Turn list of strings into strings without symbols ["J", "K"] -> J K spectral_str = re.sub(r"[\[\]\"\',]", "", str(spectral_types)) band_str = re.sub(r"[\[\]\"\',]", "", str(bands)) vsini_str = re.sub(r"[\[\]\"\',]", "", str(vsini)) res_str = re.sub(r"[\[\]\"\',]", "", str(resolution)) sampling_str = re.sub(r"[\[\]\"\',]", "", str(sampling)) print( ( "\nFor just this file I suggest you run\n\tpython nIR_run.py -s {0} -b {1} -v {2} -R {3} " "--sample_rate {4}\nOr for all the combinations you ran here\n\tpython nIR_run.py -s {5}" " -b {6} -v {7} -R {8} --sample_rate {9}" "" ).format( star, band, vel, res, smpl, spectral_str, band_str, vsini_str, res_str, sampling_str, ) ) raise if len(wav_stellar) == 0 or len(flux_stellar) == 0: raise Exception("The file {0} is empty".format(file_to_read)) # Removing boundary effects wav_stellar = wav_stellar[2:-2] flux_stellar = flux_stellar[2:-2] # sample was left aside because only one value existed # TODO: Add metallicity and logg into id string id_string = "{0:s}-{1:s}-{2:.1f}-{3:s}".format(star, band, float(vel), res) # Getting the wav, flux and mask values from the atm model # that are the closest to the stellar wav values, see # https://stackoverflow.com/questions/2566412/find-nearest-value-in-numpy-array index_atm = np.searchsorted(wav_atm, wav_stellar) # replace indexes outside the array, at the very end, by the value at the very end # index_atm = [index if(index < len(wav_atm)) else len(wav_atm)-1 for index in index_atm] indx_mask = index_atm >= len(wav_atm) # find broken indexs index_atm[indx_mask] = len(wav_atm) - 1 # replace with index of end. wav_atm_selected = wav_atm[index_atm] flux_atm_selected = flux_atm[index_atm] mask_atm_selected = mask_atm[index_atm] # Check mask masks out deep atmosphere absorption if np.any(flux_atm_selected[mask_atm_selected] < 0.98): print( "####WARNGING####\nThis absorption mask does not mask out deep atmosphere transmission!" ) print( "Min flux_atm_selected[mask_atm_selected] = {} < 0.98\n####".format( np.min(flux_atm_selected[mask_atm_selected]) ) ) # Normalize to SNR 100 in middle of J band 1.25 micron! # flux_stellar = normalize_flux(flux_stellar, id_string) # flux_stellar = snrnorm.normalize_flux(flux_stellar, id_string, new=True) # snr=100, ref_band="J" flux_stellar = eniric.obsolete.snr_norm.normalize_flux( flux_stellar, id_string, new=new, snr=snr, ref_band=ref_band, sampling=smpl, ) if id_string in [ "M0-J-1.0-100k", "M3-J-1.0-100k", "M6-J-1.0-100k", "M9-J-1.0-100k", ]: index_ref = np.searchsorted( wav_stellar, 1.25 ) # searching for the index closer to 1.25 micron snr_estimate = np.sqrt( np.sum(flux_stellar[index_ref - 1 : index_ref + 2]) ) print( "\tSanity Check: The S/N for the {0:s} reference model was of {1:4.2f}.".format( id_string, snr_estimate ) ) elif "J" in id_string: index_ref = np.searchsorted( wav_stellar, 1.25 ) # searching for the index closer to 1.25 micron snr_estimate = np.sqrt( np.sum(flux_stellar[index_ref - 1 : index_ref + 2]) ) print( "\tSanity Check: The S/N for the {0:s} non-reference model was of {1:4.2f}.".format( id_string, snr_estimate ) ) # Precision given by the first method: print("Performing analysis for: ", id_string) prec_1 = Qcalculator.rv_precision(wav_stellar, flux_stellar, grad=grad) # Precision as given by the second_method wav_stellar_chunks, flux_stellar_chunks = eniric.legacy.mask_clumping( wav_stellar, flux_stellar, mask_atm_selected ) prec_2_old = eniric.legacy.RVprec_calc_masked( wav_stellar_chunks, flux_stellar_chunks, grad=grad ) prec_2 = eniric.legacy.RVprec_calc_masked( wav_stellar, flux_stellar, mask_atm_selected, grad=grad ) assert np.all(prec_2_old == prec_2) """ # histogram checking lengths = [len(chunk) for chunk in flux_stellar_chunks_unformatted] n, bins, patches = plt.hist(lengths, 500, range=[0.5, 500.5], histtype='stepfilled') plt.title(id_string) plt.show() """ # Precision as given by the third_method prec_3 = Qcalculator.rv_precision( wav_stellar, flux_stellar, mask=flux_atm_selected ** 2, grad=grad ) # Adding Precision results to the dictionary results[id_string] = [prec_1, prec_2, prec_3] # Prepare/Do for the plotting. if plot_ste or plot_ste == id_string: plt_functions.plot_stellar_spectum( wav_stellar, flux_stellar, wav_atm_selected, mask_atm_selected ) plot_ids = [ "M3-Z-1.0-100k", "M3-Y-1.0-100k", "M3-J-1.0-100k", "M3-H-1.0-100k", "M3-K-1.0-100k", ] if plot_flux and id_string in plot_ids: wav_plot_m0.append(wav_stellar) flux_plot_m0.append(flux_stellar) if plot_flux and id_string in plot_ids: wav_plot_m3.append(wav_stellar) flux_plot_m3.append(flux_stellar) if plot_flux and id_string in plot_ids: wav_plot_m6.append(wav_stellar) flux_plot_m6.append(flux_stellar) if plot_flux and id_string in plot_ids: wav_plot_m9.append(wav_stellar) flux_plot_m9.append(flux_stellar) if plot_flux: plt_functions.plot_nIR_flux() if paper_plots: plt_functions.plot_paper_plots() else: return results