I/O and VOSA helper functions ============================= Reading photometric data ------------------------ From VOSA files ~~~~~~~~~~~~~~~ .. code:: ipython3 import src.binary_sed_fitting as bsf file_name = 'data/vosa_results/WOCS2002.bfit.phot.dat' data = bsf.load_data(file_name, mode='vosa') data .. parsed-literal:: /Users/vikrantjadhav/Documents/work/Binary_SED_Fitting/src/binary_sed_fitting.py:158: FutureWarning: The 'delim_whitespace' keyword in pd.read_csv is deprecated and will be removed in a future version. Use ``sep='\s+'`` instead data = pd.read_csv(file_name, engine='python', comment='#', .. raw:: html
wavelength flux error
FilterID
Astrosat/UVIT.F148W 1481.000000 2.548070e-15 1.361179e-16
Astrosat/UVIT.F154W 1541.000000 2.285731e-15 1.368403e-16
Astrosat/UVIT.F169M 1608.000000 2.360782e-15 1.261129e-16
GALEX/GALEX.NUV 2303.366368 3.296702e-15 8.677147e-17
KPNO/Mosaic.B 4357.276538 9.309407e-14 6.130611e-15
GAIA/GAIA3.Gbp 5035.750275 1.028575e-13 3.881303e-16
KPNO/Mosaic.V 5366.240786 1.079375e-13 7.108112e-15
GAIA/GAIA3.G 5822.388714 9.174216e-14 2.539155e-16
GAIA/GAIA3.Grp 7619.959993 7.878734e-14 3.154436e-16
KPNO/Mosaic.I 8101.609574 4.470797e-14 2.944196e-15
GAIA/GAIA3.Grvs 8578.159519 6.896280e-14 5.559650e-16
2MASS/2MASS.J 12350.000000 3.612486e-14 7.319890e-16
2MASS/2MASS.H 16620.000000 1.882778e-14 3.468206e-16
2MASS/2MASS.Ks 21590.000000 7.827519e-15 1.297694e-16
WISE/WISE.W1 33526.000000 1.546087e-15 2.990397e-17
WISE/WISE.W2 46028.000000 4.313308e-16 7.150866e-18
WISE/WISE.W3 115608.000000 1.230361e-17 4.306178e-19
From a CSV file ~~~~~~~~~~~~~~~ - The flux has to be extinction corrected - units of flux = erg/s/A/cm2 - units of wavelength = A .. code:: ipython3 import src.binary_sed_fitting as bsf file_name = 'data/extinction_corrected_flux_files/WOCS2002.csv' data = bsf.load_data(file_name, mode='csv') data .. raw:: html
wavelength flux error
FilterID
Astrosat/UVIT.F148W 1481.000000 2.548070e-15 1.361179e-16
Astrosat/UVIT.F154W 1541.000000 2.285731e-15 1.368403e-16
Astrosat/UVIT.F169M 1608.000000 2.360782e-15 1.261129e-16
GALEX/GALEX.NUV 2303.366368 3.296702e-15 8.677147e-17
KPNO/Mosaic.B 4357.276538 9.309407e-14 6.130611e-15
GAIA/GAIA3.Gbp 5035.750275 1.028575e-13 3.881303e-16
KPNO/Mosaic.V 5366.240786 1.079375e-13 7.108112e-15
GAIA/GAIA3.G 5822.388714 9.174216e-14 2.539155e-16
GAIA/GAIA3.Grp 7619.959993 7.878734e-14 3.154436e-16
KPNO/Mosaic.I 8101.609574 4.470797e-14 2.944196e-15
GAIA/GAIA3.Grvs 8578.159519 6.896280e-14 5.559650e-16
2MASS/2MASS.J 12350.000000 3.612486e-14 7.319890e-16
2MASS/2MASS.H 16620.000000 1.882778e-14 3.468206e-16
2MASS/2MASS.Ks 21590.000000 7.827519e-15 1.297694e-16
WISE/WISE.W1 33526.000000 1.546087e-15 2.990397e-17
WISE/WISE.W2 46028.000000 4.313308e-16 7.150866e-18
WISE/WISE.W3 115608.000000 1.230361e-17 4.306178e-19
Reading model files ------------------- .. code:: ipython3 import xarray as xr import src.binary_sed_fitting as bsf da = xr.open_dataarray(bsf.DIR_MODELS+'koester_synthetic_photometry.nc') da .. raw:: html
<xarray.DataArray (FilterID: 8162, Te: 82, logg: 13)> Size: 70MB
    [8700692 values with dtype=float64]
    Coordinates:
      * FilterID  (FilterID) <U38 1MB 'IUE/IUE.1250-1300' ... 'QUIJOTE/MFI.11GHz_H3'
      * Te        (Te) int32 328B 5000 5250 5500 5750 ... 50000 60000 70000 80000
      * logg      (logg) float64 104B 6.5 6.75 7.0 7.25 7.5 ... 8.75 9.0 9.25 9.5
    Attributes:
        Wavelengths:  [1.28470318e+03 1.35336435e+03 1.35623969e+03 ... 3.8683349...
        unit:         erg/s/cm2/A
        long_name:    Flux
Creating VOSA input files ------------------------- VOSA input format ~~~~~~~~~~~~~~~~~ VOSA requires following format for uploading the photometric information files +------+------+------+------+------+------+------+------+------+------+ | ob | RA | DEC | dis | Av | fi | flux | e | pnt | obj | | ject | | | | | lter | | rror | opts | opts | +======+======+======+======+======+======+======+======+======+======+ | — | — | — | — | — | — | — | — | — | — | +------+------+------+------+------+------+------+------+------+------+ Identify the filters in the files you are uploading (create the “filter_list” accordingly) Create a file with “name, ra, dec, magnitudes and magnitude errors”. This “photomety_file” be converted to VOSA format - Note: This code is for a cluster, hence distance and extinction is kept constant The VOSA_input.txt file has magnitudes in the “flux” column. So while uploading to VOSA, keep “file type” as “magnitudes” .. code:: ipython3 import pandas as pd import numpy as np df_photometry = pd.read_csv('data/example_photomety_file.csv', engine='python') df_photometry.set_index('name', inplace=True) # Adding distance and Av values distance = '831.76+-11' # [pc] Av = '0.1736+-0.017' # 3.1 * E(B-V) [mag] df_photometry['distance'] = distance df_photometry['Av'] = Av print((df_photometry.columns)) df_photometry.head() .. parsed-literal:: Index(['ra', 'dec', 'B', 'e_B', 'V', 'e_V', 'I', 'e_I', 'U', 'e_U', 'R', 'e_R', 'F148W', 'e_F148W', 'F154W', 'e_F154W', 'F169M', 'e_F169M', 'distance', 'Av'], dtype='object') .. raw:: html
ra dec B e_B V e_V I e_I U e_U R e_R F148W e_F148W F154W e_F154W F169M e_F169M distance Av
name
WOCS2002 132.8492 11.83040 12.300 NaN 11.540 NaN 11.060 NaN NaN NaN NaN NaN 18.66000 0.058 18.69300 0.065 18.58200 0.058 831.76+-11 0.1736+-0.017
WOCS1007 132.8931 11.85297 11.070 NaN 10.960 NaN 11.072 NaN NaN NaN NaN NaN 17.03341 0.018 16.87171 0.016 16.63688 0.019 831.76+-11 0.1736+-0.017
Y1168 132.8331 11.81147 18.409 NaN 18.632 NaN NaN NaN 18.393 NaN NaN NaN 17.02925 0.039 17.06582 0.033 17.17563 0.033 831.76+-11 0.1736+-0.017
Renaming the columns with SVO Filter Profile Service names ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - http://svo2.cab.inta-csic.es/theory/fps/index.php?mode=browse .. code:: ipython3 filter_list = ['KPNO/Mosaic.B', 'KPNO/Mosaic.V','KPNO/Mosaic.I', 'KPNO/Mosaic.U','KPNO/Mosaic.R', 'Astrosat/UVIT.F148W','Astrosat/UVIT.F154W', 'Astrosat/UVIT.F169M'] df_photometry.rename(columns={'ra' : 'ra', 'dec' : 'dec', 'B' : 'KPNO/Mosaic.B', 'e_B' : 'e_KPNO/Mosaic.B', 'V' : 'KPNO/Mosaic.V', 'e_V' : 'e_KPNO/Mosaic.V', 'I' : 'KPNO/Mosaic.I', 'e_I' : 'e_KPNO/Mosaic.I', 'U' : 'KPNO/Mosaic.U', 'e_U' : 'e_KPNO/Mosaic.U', 'R' : 'KPNO/Mosaic.R', 'e_R' : 'e_KPNO/Mosaic.R', 'F148W' : 'Astrosat/UVIT.F148W', 'e_F148W' : 'e_Astrosat/UVIT.F148W', 'F154W' : 'Astrosat/UVIT.F154W', 'e_F154W' : 'e_Astrosat/UVIT.F154W', 'F169M' : 'Astrosat/UVIT.F169M', 'e_F169M' : 'e_Astrosat/UVIT.F169M', 'distance': 'distance', 'Av' : 'Av'}, inplace=True) df_photometry.head() .. raw:: html
ra dec KPNO/Mosaic.B e_KPNO/Mosaic.B KPNO/Mosaic.V e_KPNO/Mosaic.V KPNO/Mosaic.I e_KPNO/Mosaic.I KPNO/Mosaic.U e_KPNO/Mosaic.U KPNO/Mosaic.R e_KPNO/Mosaic.R Astrosat/UVIT.F148W e_Astrosat/UVIT.F148W Astrosat/UVIT.F154W e_Astrosat/UVIT.F154W Astrosat/UVIT.F169M e_Astrosat/UVIT.F169M distance Av
name
WOCS2002 132.8492 11.83040 12.300 NaN 11.540 NaN 11.060 NaN NaN NaN NaN NaN 18.66000 0.058 18.69300 0.065 18.58200 0.058 831.76+-11 0.1736+-0.017
WOCS1007 132.8931 11.85297 11.070 NaN 10.960 NaN 11.072 NaN NaN NaN NaN NaN 17.03341 0.018 16.87171 0.016 16.63688 0.019 831.76+-11 0.1736+-0.017
Y1168 132.8331 11.81147 18.409 NaN 18.632 NaN NaN NaN 18.393 NaN NaN NaN 17.02925 0.039 17.06582 0.033 17.17563 0.033 831.76+-11 0.1736+-0.017
Creating the VOSA compliant input file from the dataframe ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: ipython3 def create_VOSA_input_file(df_photometry, filter_list, output_name=None): # combining data from all stars to make the VOSA upload file df_VOSA_input = pd.DataFrame(columns = ['object', 'ra', 'dec','distance','Av','filter','flux','error','pntopts','objopts']) counter=0 for name in df_photometry.index: for filter_name in filter_list: df_VOSA_input.loc[counter, 'object'] = name df_VOSA_input.loc[counter, 'ra'] = df_photometry['ra'][name] df_VOSA_input.loc[counter, 'dec'] = df_photometry['dec'][name] df_VOSA_input.loc[counter, 'distance'] = df_photometry['distance'][name] df_VOSA_input.loc[counter, 'Av'] = df_photometry['Av'][name] df_VOSA_input.loc[counter, 'filter'] = filter_name df_VOSA_input.loc[counter, 'flux'] = df_photometry[filter_name][name] df_VOSA_input.loc[counter, 'error'] = df_photometry['e_'+filter_name][name] df_VOSA_input.loc[counter, 'pntopts'] = '---' df_VOSA_input.loc[counter, 'objopts'] = '---' # Rewriting the row if flux is not available for this star-filter combination if ~np.isnan(df_photometry[filter_name][name]): counter=counter+1 df_VOSA_input.fillna('---', inplace=True) if output_name !=None: df_VOSA_input.to_csv(output_name, header=None, index=None, sep=' ') return df_VOSA_input create_VOSA_input_file(df_photometry, filter_list, output_name='data/example_VOSA_input_file.txt') .. parsed-literal:: /var/folders/2v/ztlgg9951mdc3j88_z3gbscc0000gn/T/ipykernel_5393/3182199717.py:21: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)` df_VOSA_input.fillna('---', inplace=True) .. raw:: html
object ra dec distance Av filter flux error pntopts objopts
0 WOCS2002 132.8492 11.83040 831.76+-11 0.1736+-0.017 KPNO/Mosaic.B 12.30000 --- --- ---
1 WOCS2002 132.8492 11.83040 831.76+-11 0.1736+-0.017 KPNO/Mosaic.V 11.54000 --- --- ---
2 WOCS2002 132.8492 11.83040 831.76+-11 0.1736+-0.017 KPNO/Mosaic.I 11.06000 --- --- ---
3 WOCS2002 132.8492 11.83040 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F148W 18.66000 0.058 --- ---
4 WOCS2002 132.8492 11.83040 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F154W 18.69300 0.065 --- ---
5 WOCS2002 132.8492 11.83040 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F169M 18.58200 0.058 --- ---
6 WOCS1007 132.8931 11.85297 831.76+-11 0.1736+-0.017 KPNO/Mosaic.B 11.07000 --- --- ---
7 WOCS1007 132.8931 11.85297 831.76+-11 0.1736+-0.017 KPNO/Mosaic.V 10.96000 --- --- ---
8 WOCS1007 132.8931 11.85297 831.76+-11 0.1736+-0.017 KPNO/Mosaic.I 11.07200 --- --- ---
9 WOCS1007 132.8931 11.85297 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F148W 17.03341 0.018 --- ---
10 WOCS1007 132.8931 11.85297 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F154W 16.87171 0.016 --- ---
11 WOCS1007 132.8931 11.85297 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F169M 16.63688 0.019 --- ---
12 Y1168 132.8331 11.81147 831.76+-11 0.1736+-0.017 KPNO/Mosaic.B 18.40900 --- --- ---
13 Y1168 132.8331 11.81147 831.76+-11 0.1736+-0.017 KPNO/Mosaic.V 18.63200 --- --- ---
14 Y1168 132.8331 11.81147 831.76+-11 0.1736+-0.017 KPNO/Mosaic.U 18.39300 --- --- ---
15 Y1168 132.8331 11.81147 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F148W 17.02925 0.039 --- ---
16 Y1168 132.8331 11.81147 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F154W 17.06582 0.033 --- ---
17 Y1168 132.8331 11.81147 831.76+-11 0.1736+-0.017 Astrosat/UVIT.F169M 17.17563 0.033 --- ---
Now upload the file at http://svo2.cab.inta-csic.es/theory/vosa/index.php?action=myfiles&otype=star&seeall= Make sure to change the File type to \`magnitude`\` Keep SED Type: Flux vs Lambda Select the file and search through VO for all possible detections Look at the SEDs, Possibly remove some telescopes (e.g. SDSS photometry is problematic for bright M67 stars, Gaia DR3 synthetic photometry may or may not be usable) Create flux corrected files from VOSA ------------------------------------- - DEPRECATED - NO LONGER REQUIRED AS ``bsf.load_data()`` CAN NOW USE VOSA FILES DIRECTLY .. code:: ipython3 import pandas as pd def create_extinction_corrected_files_from_VOSA(name, file_name, output_name, verbose=True): # Reading parameters derived by VOSA flux = pd.read_csv(file_name, engine='python', comment='#', delim_whitespace= True, skipinitialspace=True, header=None) flux.columns = ['FilterID','wavelength','Obs.Flux','Obs.Error','flux','error','model_flux_A','Fitted','Excess','FitExc','UpLim'] # Removing filters noted as "upper limit" if verbose: print('WARNING: %s removed due to upper limit'%(flux[flux['UpLim']=='1']['FilterID'].values)) flux = flux[flux['UpLim'] == '---'] flux = flux.drop(columns=['Obs.Flux','Obs.Error','Fitted','Excess','FitExc','UpLim','model_flux_A']) flux.to_csv(output_name, index=False) return flux DIR_OBS = 'data/' for idx, name in enumerate(['WOCS2002','WOCS1007','Y1168']): print(name) # file_name = DIR_OBS + name +'/bestfitp/'+ name +'.bfit.phot.dat' file_name = 'data/vosa_results/%s.bfit.phot.dat'%name flux = create_extinction_corrected_files_from_VOSA(name,file_name, output_name='data/extinction_corrected_flux_files/'+name+'.csv') .. parsed-literal:: WOCS2002 WARNING: ['WISE/WISE.W4'] removed due to upper limit WOCS1007 WARNING: ['WISE/WISE.W4'] removed due to upper limit Y1168 WARNING: ['WISE/WISE.W3' 'WISE/WISE.W4'] removed due to upper limit .. parsed-literal:: /var/folders/2v/ztlgg9951mdc3j88_z3gbscc0000gn/T/ipykernel_5393/1800319444.py:4: FutureWarning: The 'delim_whitespace' keyword in pd.read_csv is deprecated and will be removed in a future version. Use ``sep='\s+'`` instead flux = pd.read_csv(file_name, engine='python', comment='#', delim_whitespace= True, skipinitialspace=True, header=None) /var/folders/2v/ztlgg9951mdc3j88_z3gbscc0000gn/T/ipykernel_5393/1800319444.py:4: FutureWarning: The 'delim_whitespace' keyword in pd.read_csv is deprecated and will be removed in a future version. Use ``sep='\s+'`` instead flux = pd.read_csv(file_name, engine='python', comment='#', delim_whitespace= True, skipinitialspace=True, header=None) /var/folders/2v/ztlgg9951mdc3j88_z3gbscc0000gn/T/ipykernel_5393/1800319444.py:4: FutureWarning: The 'delim_whitespace' keyword in pd.read_csv is deprecated and will be removed in a future version. Use ``sep='\s+'`` instead flux = pd.read_csv(file_name, engine='python', comment='#', delim_whitespace= True, skipinitialspace=True, header=None) Logo ---- .. code:: ipython3 import xarray as xr import src.binary_sed_fitting as bsf import matplotlib.pyplot as plt da = xr.open_dataarray(bsf.DIR_MODELS+'koester_spectral_library.nc') y1 = da.sel(Te=6000).sel(logg=7.0)*4e2 y2 = da.sel(Te=15000).sel(logg=7.0)*1.5 plt.style.use('dark_background') fig, ax = plt.subplots(figsize=(2,1)) ax.fill_between(da.Wavelength, y1, alpha=0.6, color='#FF6961') ax.fill_between(da.Wavelength, y2, alpha=0.6, color='#6198ff') ax.loglog() ax.set_xlim(969,8000) ax.set_ylim(3000000) ax.axis('off') ax.text(0.5, 0.5, 'Binary \n SED \n Fitting', fontsize=14, transform=ax.transAxes, va='center', ha='center', color='white', family='serif', variant='small-caps', weight='bold') plt.savefig('plots/logo.png', dpi=200, bbox_inches='tight') .. image:: examples_io/output_19_0.png