diff --git a/.github/workflows/sphinx-build.yml b/.github/workflows/sphinx-build.yml new file mode 100644 index 00000000..c7d1d6df --- /dev/null +++ b/.github/workflows/sphinx-build.yml @@ -0,0 +1,38 @@ +name: "Sphinx Docs Check" +on: + push: + paths: + - 'docs/**' + - 'Metallicity_Stack_Commons/**' + pull_request: + paths: + - 'docs/**' + - 'Metallicity_Stack_Commons/**' + +jobs: + docs: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.8'] + + steps: + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Checkout MSC + uses: actions/checkout@v2 + - name: Checkout chun_codes + uses: actions/checkout@v2 + with: + repository: astrochun/chun_codes + path: chun_codes + - name: Install chun_codes + run: | + python setup.py install + working-directory: chun_codes + - name: Sphinx build + uses: ammaraskar/sphinx-action@master + with: + docs-folder: "docs/" \ No newline at end of file diff --git a/Metallicity_Stack_Commons/__init__.py b/Metallicity_Stack_Commons/__init__.py index 0c44a122..cace546c 100644 --- a/Metallicity_Stack_Commons/__init__.py +++ b/Metallicity_Stack_Commons/__init__.py @@ -1,3 +1,6 @@ +from logging import Logger +from typing import Union + from chun_codes.cardelli import cardelli import astropy.units as u from datetime import date @@ -7,7 +10,7 @@ from .logging import log_stdout, log_verbose -version = "1.3.1" +version = "1.4.0" lambda0 = [3726.18, 4101.73, 4340.46, 4363.21, 4861.32, 4958.91, 5006.84] line_type = ['Oxy2', 'Balmer', 'Balmer', 'Single', 'Balmer', 'Single', 'Single'] @@ -51,22 +54,20 @@ k_dict = dict(zip(line_name, k_values)) -def exclude_outliers(objno, verbose=False, log=None): +def exclude_outliers(objno: Union[list, np.ndarray], verbose: bool = False, + log: Logger = log_stdout()) -> np.ndarray: """ Exclude spectra that are identified as outliers. Generally this is because the spectra have very high S/N on the continuum. - :param objno: list or numpy array of eight-digit identifier - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param objno: Array of eight-digit identifier + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return flag: numpy array of zeros and ones + :return: Array of zeros (not flagged) and ones (flagged """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) flag = np.zeros(len(objno), dtype=int) @@ -81,31 +82,29 @@ def exclude_outliers(objno, verbose=False, log=None): return flag -def dir_date(folder_name, path_init='', year=False, verbose=False, log=None): +def dir_date(folder_name: str, path_init: str = '', year: bool = False, + verbose: bool = False, log: Logger = log_stdout()) \ + -> str: """ - Purpose: - This function finds and returns the path to a directory named after the - current date (MMDDYYYY). If the directory doesn't exist yet, it creates - a new directory named after the current date in the provided folder_name - directory. + This function finds and returns the path to a directory named after the + current date (MMDDYYYY). If the directory doesn't exist yet, it creates + a new directory named after the current date in the provided + ``folder_name`` directory. - From https://github.com/rafia37/Evolution-of-Galaxies/blob/master/general.py + Originally from https://github.com/rafia37/Evolution-of-Galaxies/blob/master/general.py Usage: - fitspath = dir_date(folder_name, path_init='', year=True) + fitspath = dir_date(folder_name, year=True) - :param folder_name: str containing directory for date subdirectory will be in + :param folder_name: Directory for date subdirectory will be in :param path_init: root path. Default: empty string :param year: Indicate whether to include year in date folder. Default: False - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return fitspath: Full path to the date directory + :return: Full path to the date directory """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) today = date.today() @@ -125,10 +124,17 @@ def dir_date(folder_name, path_init='', year=False, verbose=False, log=None): return fitspath -def get_user(username=None, verbose=False, log=None): +def get_user(username: Union[None, str] = None, + verbose: bool = False, log: Logger = log_stdout()) -> str: + """ + Get the corresponding path for a given ``username`` + + :param username: Optional input for username + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - if log is None: - log = log_stdout() + :return: Full path to the date directory + """ log_verbose(log, "starting ...", verbose=verbose) diff --git a/Metallicity_Stack_Commons/analysis/attenuation.py b/Metallicity_Stack_Commons/analysis/attenuation.py index ad688efd..d5daf134 100644 --- a/Metallicity_Stack_Commons/analysis/attenuation.py +++ b/Metallicity_Stack_Commons/analysis/attenuation.py @@ -1,3 +1,6 @@ +from logging import Logger +from typing import Union, Tuple + import numpy as np from .. import k_dict, line_name_short @@ -19,24 +22,27 @@ k_HDELTA = k_dict[HD] -def compute_EBV(ratio, source='HgHb', zero_neg=True, verbose=False, log=None): - """ - Purpose: - Determines E(B-V) from Hg/Hb or Hd/Hb flux ratios using Case B assumptions - - :param ratio: float or numpy array containing Hg/Hb or Hd/Hb - :param source: str indicate ratio type. Either 'HgHb' or 'HdHb'. Default: 'HgHb' - :param zero_neg: boolean to indicate whether to zero out negative reddening. Default: True - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object - - :return EBV: float or numpy array containing E(B-V). - Note: Not correcting for negative reddening - :return EBV_peak: float or numpy array return when it is a 2-D distribution +def compute_EBV(ratio: Union[float, np.ndarray], source: str = 'HgHb', + zero_neg: bool = True, verbose: bool = False, + log: Logger = log_stdout()) -> \ + Union[float, np.ndarray, Tuple[np.ndarray, np.ndarray]]: """ + Determines E(B-V) from Hg/Hb or Hd/Hb flux ratios using Case B assumptions + + :param ratio: Float or array containing Hg/Hb or Hd/Hb values + :param source: Indicate ratio type. Either 'HgHb' or 'HdHb'. + Default: 'HgHb' + :param zero_neg: Indicate whether to zero out negative reddening. + Default: True + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - if log is None: - log = log_stdout() + :return: E(B-V) values, E(B-V) peak values + + Note: + When only E(B-V) values is returned, correction does not account + for negative reddening + """ log_verbose(log, "starting ...", verbose=verbose) @@ -87,42 +93,56 @@ def compute_EBV(ratio, source='HgHb', zero_neg=True, verbose=False, log=None): return EBV -def compute_A(EBV, verbose=False, log=None): +def compute_A(EBV: float, verbose: bool = False, + log: Logger = log_stdout()) -> dict: """ - Purpose: - Compute A(Lambda) for all possible emission lines + Compute A(Lambda) for all possible emission lines - :param EBV: float value of E(B-V) - Has not been configured to handle a large array. Some array handling would be needed - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param EBV: E(B-V) value + Has not been configured to handle a large array. + Some array handling would be needed - :return A_dict: dict containing A(lambda) with keys identical to k_dict - """ + :param verbose: Write verbose message to stdout. + Default: file only + :param log: logging.Logger object - if log is None: - log = log_stdout() + :return: A(lambda) with keys identical to ``k_dict`` + """ log_verbose(log, "starting ...", verbose=verbose) - k_arr = np.array(list(k_dict.values())) + k_arr = np.array(list(k_dict.values())) - A_arr = k_arr * EBV + A_arr = k_arr * EBV A_dict = dict(zip(list(k_dict.keys()), A_arr)) log_verbose(log, "finished.", verbose=verbose) return A_dict -def line_ratio_atten(ratio, EBV, wave_top, wave_bottom, verbose=False, - log=None): +def line_ratio_atten(ratio: Union[float, np.ndarray], + EBV: Union[float, np.ndarray], + wave_top: str, wave_bottom: str, + verbose: bool = False, + log: Logger = log_stdout()) -> \ + Union[float, np.ndarray]: + """ + Determine dust-corrected emission-line ratios - if log is None: - log = log_stdout() + :param ratio: Float or array of observed flux ratios + :param EBV: E(B-V) value(s) + :param wave_top: Emission-line name for flux ratio numerator + :param wave_bottom: Emission-line name for flux ratio denominator + :param verbose: Write verbose message to stdout. + Default: file only + :param log: logging.Logger object + + :return: Float or array of dust-corrected flux ratios + """ log_verbose(log, "starting ...", verbose=verbose) - k_top = k_dict[wave_top] + k_top = k_dict[wave_top] k_bottom = k_dict[wave_bottom] ratio_atten = ratio * 10**(0.4*EBV*(k_top - k_bottom)) @@ -131,28 +151,26 @@ def line_ratio_atten(ratio, EBV, wave_top, wave_bottom, verbose=False, return ratio_atten -def Hb_SFR(log_LHb, EBV, verbose=False, log=None): +def Hb_SFR(log_LHb: Union[float, np.ndarray], + EBV: Union[float, np.ndarray], + verbose: bool = False, + log: Logger = log_stdout()) -> \ + Union[float, np.ndarray]: """ - Purpose: - Determine dust-corrected SFR using the H-beta luminosity and a - measurement for nebular attenuation + Determine dust-corrected SFR using the H-beta luminosity and a + measurement for nebular attenuation Equation below is based on Eq. 2 in Ly et al. (2015), ApJ, 805, 45 DOI: https://doi.org/10.1088/0004-637X/805/1/45 - :param log_LHb: numpy array or float containing logarithm of H-beta - luminosity in units of erg/s - :param EBV: numpy array or float providing E(B-V) - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param log_LHb: Logarithm of H-beta luminosity in units of erg/s + :param EBV: E(B-V) value(s) + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return logSFR: numpy array or float containing the SFR in - logarithmic units of M_sun/yr + :return: SFRs in logarithmic units of M_sun/yr """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) logSFR = np.log10(4.4e-42 * HaHb_CaseB) + 0.4*EBV*k_HBETA + log_LHb diff --git a/Metallicity_Stack_Commons/analysis/composite_indv_detect.py b/Metallicity_Stack_Commons/analysis/composite_indv_detect.py index 2b115554..dc1197f0 100644 --- a/Metallicity_Stack_Commons/analysis/composite_indv_detect.py +++ b/Metallicity_Stack_Commons/analysis/composite_indv_detect.py @@ -1,3 +1,5 @@ +from logging import Logger + from os.path import join from os.path import exists @@ -21,40 +23,41 @@ three_beta_name = indv_names0[6] -def main(fitspath, dataset, revised=False, det3=True, verbose=False, log=None): +def main(fitspath: str, dataset: str, revised: bool = False, + det3: bool = True, verbose: bool = False, + log: Logger = log_stdout()): """ - Purpose: - Reads in composite table(s) containing bin information to - determine temperature-based metallicity from composite average - T_e and individual line ratios ([OII]/H-beta, [OIII]/H-beta) - - :param fitspath: str containing folder path - :param dataset: str containing sub-folder (specific to stacking approach) - :param revised: Bool indicates whether to use revised bin properties - (e.g., *.revised.tbl files) - :param det3: Bool indicates whether individual galaxy files is limited to + Reads in composite table(s) containing bin information to + determine temperature-based metallicity from composite average + T_e and individual line ratios ([OII]/H-beta, [OIII]/H-beta) + + :param fitspath: Folder full path + :param dataset: Sub-folder path (specific to stacking approach) + :param revised: Indicates whether to use revised bin properties + (e.g., revised.tbl files). Default: False + :param det3: Indicates whether individual galaxy files is limited to those satisfying emission-line det3 requirement Default: True - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object - - Files identified by default - composite_file: str containing filename of composite data - e.g., '[dataset]/bin_derived_properties.tbl' or - '[dataset]/bin_derived_properties.revised.tbl' - indv_em_line_file: str containing filename that contains - emission-line information for each galaxy + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object + + Files identified by default: + + composite_file: Filename of composite data + e.g., '[dataset]/bin_derived_properties.tbl', + '[dataset]/bin_derived_properties.revised.tbl' + + indv_em_line_file: Filename that contains emission-line information + for each galaxy e.g., 'individual_properties.tbl' - indv_bin_file: str containing filename tha contains bin information - for each galaxy + + indv_bin_file: Filename that contains bin information for each galaxy e.g., '[dataset]/individual_bin_info.tbl' - outfile: str containing filename of output file + + outfile: Filename of output file e.g., '[dataset]/individual_derived_properties.tbl' """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) # Define [composite_file] diff --git a/Metallicity_Stack_Commons/analysis/error_prop.py b/Metallicity_Stack_Commons/analysis/error_prop.py index e4535df6..1ddc85a8 100644 --- a/Metallicity_Stack_Commons/analysis/error_prop.py +++ b/Metallicity_Stack_Commons/analysis/error_prop.py @@ -1,3 +1,4 @@ +from logging import Logger from os.path import join, exists from chun_codes import random_pdf, compute_onesig_pdf @@ -15,23 +16,18 @@ from ..logging import log_stdout, log_verbose -def write_npz(path, npz_files, dict_list, verbose=False, log=None): +def write_npz(path: str, npz_files: list, dict_list: list, + verbose: bool = False, log: Logger = log_stdout()): """ - Purpose: - Write numpy files with provided dictionaries + Write numpy files with provided dictionaries - :param path: str - prefix for filename output - :param npz_files: list - contains npz file names - :param dict_list: list - contains dictionaries for each corresponding npz file - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object - - :return: Write npz files + :param path: Prefix for filename output + :param npz_files: NPZ file names + :param dict_list: List of dict for each corresponding npz file + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) for file, dict_input in zip(npz_files, dict_list): @@ -45,27 +41,25 @@ def write_npz(path, npz_files, dict_list, verbose=False, log=None): log_verbose(log, "finished.", verbose=verbose) -def fluxes_derived_prop(path, raw=False, binned_data=True, apply_dust=False, - revised=True, verbose=False, log=None): +def fluxes_derived_prop(path: str, raw: bool = False, + binned_data: bool = True, apply_dust: bool = False, + revised: bool = True, verbose: bool = False, + log: Logger = log_stdout()): """ - Purpose: - Use measurements and their uncertainties to perform a randomization - approach. The randomization is performed on individual emission lines. - It carries that information to derived flux ratios and then - determines electron temperature and metallicity - - :param path: str of full path - :param raw: bool to do a simple calculation, no randomization. Default: False - :param binned_data: bool for whether to analysis binned data. Default: True - :param apply_dust: bool for whether to apply dust attenuation. Default: False - :param revised: bool to indicate if revised validation table is used. Default: True - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + Use measurements and their uncertainties to perform a randomization + approach. The randomization is performed on individual emission lines. + It carries that information to derived flux ratios and then + determines electron temperature and metallicity + + :param path: Full path + :param raw: Do a simple calculation, no randomization. Default: False + :param binned_data: Whether to analyze binned data. Default: True + :param apply_dust: Whether to apply dust attenuation. Default: False + :param revised: Indicate if revised validation table is used. Default: True + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) # Define files to read in for binned data @@ -144,10 +138,14 @@ def fluxes_derived_prop(path, raw=False, binned_data=True, apply_dust=False, # if apply_dust: - EBV = compute_EBV(flux_ratios_dict[dust[0]], source=dust[0], - verbose=verbose, log=log) - EBV_HdHb = compute_EBV(flux_ratios_dict[dust[1]], source=dust[1], - verbose=verbose, log=log) + EBV = compute_EBV(flux_ratios_dict[dust[0]], + source=dust[0].replace('_composite', ''), + verbose=verbose, + log=log) + EBV_HdHb = compute_EBV(flux_ratios_dict[dust[1]], + source=dust[1].replace('_composite', ''), + verbose=verbose, + log=log) else: EBV = None EBV_HdHb = None @@ -256,9 +254,11 @@ def fluxes_derived_prop(path, raw=False, binned_data=True, apply_dust=False, dust[2] + '_low_err': np.repeat(np.nan, len(prop_tab0)), dust[2] + '_high_err': np.repeat(np.nan, len(prop_tab0))} - EBV, EBV_peak = compute_EBV(flux_ratios_dict[dust[0]], - source=dust[0], verbose=verbose, - log=log) + EBV, \ + EBV_peak = compute_EBV(flux_ratios_dict[dust[0]], + source=dust[0].replace('_composite', ''), + verbose=verbose, + log=log) err_prop, peak_prop = compute_onesig_pdf(EBV, EBV_peak, usepeak=True) @@ -273,9 +273,10 @@ def fluxes_derived_prop(path, raw=False, binned_data=True, apply_dust=False, dust[3] + '_low_err': np.repeat(np.nan, len(prop_tab0)), dust[3] + '_high_err': np.repeat(np.nan, len(prop_tab0))} - EBV_HdHb, EBV_HdHb_peak = compute_EBV(flux_ratios_dict[dust[1]], - source=dust[1], - verbose=verbose, log=log) + EBV_HdHb, \ + EBV_HdHb_peak = compute_EBV(flux_ratios_dict[dust[1]], + source=dust[1].replace('_composite', ''), + verbose=verbose, log=log) log.info(EBV_HdHb_peak) err_prop, peak_prop = compute_onesig_pdf(EBV_HdHb, EBV_HdHb_peak, diff --git a/Metallicity_Stack_Commons/analysis/fitting.py b/Metallicity_Stack_Commons/analysis/fitting.py index 380a167c..61d2e153 100644 --- a/Metallicity_Stack_Commons/analysis/fitting.py +++ b/Metallicity_Stack_Commons/analysis/fitting.py @@ -1,3 +1,5 @@ +from logging import Logger +from typing import Union import numpy as np from astropy.convolution import Box1DKernel, convolve from astropy.io import ascii as asc @@ -9,37 +11,35 @@ con1 = wavelength_dict['OII_3729'] / wavelength_dict['OII_3726'] -def gauss(x, xbar, s, a, c): +def gauss(x: np.ndarray, xbar: float, s: float, a: float, c: float) \ + -> np.ndarray: """ - Purpose: - Function providing Gaussian profile for curve_fit + Function providing Gaussian profile for curve_fit - :param x: wavelength array - :param xbar: central wavelength of Gaussian fit - :param s: sigma (width) of Gaussian fit - :param a: amplitude of Gaussian fit - :param c: continuum constant for Gaussian fit + :param x: Wavelength array + :param xbar: Central wavelength of Gaussian fit + :param s: Sigma (width) of Gaussian fit + :param a: Amplitude of Gaussian fit + :param c: Continuum constant for Gaussian fit - :return: - Gaussian fit + :return: Gaussian fit """ return a * np.exp(-(x - xbar) ** 2 / (2 * s ** 2)) + c -def double_gauss(x, xbar, s1, a1, c, s2, a2): +def double_gauss(x: np.ndarray, xbar: float, s1: float, a1: float, c: float, + s2: float, a2: float) -> np.array: """ - Purpose: - Function providing double Gaussian profile (emission and absorption) - for curve_fit - - :param x: wavelength array - :param xbar: central wavelength of Gaussian fit - :param s1: sigma (width) of first Gaussian fit - :param a1: amplitude of first Gaussian fit - :param c: continuum constant for Gaussian fit + Function providing double Gaussian profile (emission and absorption) + for curve_fit - :param s2: sigma (width) of second Gaussian fit - :param a2: amplitude of second Gaussian fit + :param x: Wavelength array + :param xbar: Central wavelength of Gaussian fit + :param s1: Sigma (width) of first Gaussian fit (positive) + :param a1: Amplitude of first Gaussian fit + :param c: Continuum constant for Gaussian fit + :param s2: Sigma (width) of second Gaussian fit (absorption) + :param a2: Amplitude of second Gaussian fit :return: Double Gaussian fit """ @@ -48,49 +48,44 @@ def double_gauss(x, xbar, s1, a1, c, s2, a2): a2 * np.exp(-(x - xbar) ** 2 / (2 * s2 ** 2)) -def oxy2_gauss(x, xbar, s1, a1, c, s2, a2): +def oxy2_gauss(x: np.ndarray, xbar: float, s1: float, a1: float, c: float, + s2: float, a2: float) -> np.ndarray: """ - Purpose: - Function providing [OII] doublet Gaussian profile for curve_fit + Function providing [OII] doublet Gaussian profile for curve_fit - :param x: wavelength array - :param xbar: central wavelength of [OII]3726 Gaussian fit - :param s1: sigma (width) of [OII]3726 Gaussian fit - :param a1: amplitude of [OII]3726 Gaussian fit - :param c: continuum constant for Gaussian fit - :param s2: sigma (width) of [OII]3728 Gaussian fit - :param a2: amplitude of [OII]3728 Gaussian fit + :param x: Wavelength array + :param xbar: Central wavelength of [OII]3726 Gaussian fit + :param s1: Sigma (width) of [OII]3726 Gaussian fit + :param a1: Amplitude of [OII]3726 Gaussian fit + :param c: Continuum constant for Gaussian fit + :param s2: Sigma (width) of [OII]3728 Gaussian fit + :param a2: Amplitude of [OII]3728 Gaussian fit :return: [OII] doublet Gaussian fit - """ return a1 * np.exp(-(x - xbar) ** 2 / (2 * s1 ** 2)) + c + \ a2 * np.exp(-(x - (xbar * con1)) ** 2 / (2 * s2 ** 2)) -def rms_func(wave, dispersion, lambda_in, y0, sigma_array, mask_flag, - verbose=False, log=None): +def rms_func(wave: np.ndarray, dispersion: float, lambda_in: float, + y0: np.ndarray, sigma_array: float, mask_flag: np.ndarray, + verbose: bool = False, log: Logger = log_stdout()): """ - Purpose: - Compute rms in the spectra - - :param wave: numpy array containing rest wavelengths - :param dispersion: spectral dispersion in AA/pix - :param lambda_in: central wavelength of fit - :param y0: numpy array containing spectra in units of erg/s/cm2/AA - :param sigma_array: Gaussian sigma - :param mask_flag: numpy array indicating spectra that are masked for OH - skyline contamintion - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + Compute rms in the spectra + + :param wave: Array of rest wavelengths + :param dispersion: Spectral dispersion in AA/pix + :param lambda_in: Central wavelength of fit + :param y0: Array of fluxes in units of erg/s/cm2/AA + :param sigma_array: Gaussian sigma (AA) + :param mask_flag: Indicates spectra are masked for OH skyline contamination + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object :return: """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) x_idx = np.where((np.abs(wave - lambda_in) <= 100) & (mask_flag == 0))[0] @@ -112,28 +107,26 @@ def rms_func(wave, dispersion, lambda_in, y0, sigma_array, mask_flag, return ini_sig / scalefact, RMS_pix -def OIII4363_flux_limit(combine_flux_ascii, verbose=False, log=None): +def OIII4363_flux_limit(combine_flux_file: str, verbose: bool = False, + log: Logger = log_stdout()) -> \ + Union[None, np.ndarray]: """ - Purpose: - Determine 3-sigma limit on [OIII]4363 based on H-gamma measurements + Determine 3-sigma limit on [OIII]4363 based on H-gamma measurements - :param combine_flux_ascii: filename of ASCII file containing emission-line - flux measurements - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param combine_flux_file: Filename of ASCII file containing emission-line + flux measurements + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return: numpy array containing 3-sigma flux limit + :return: Array containing 3-sigma flux limit """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) try: - combine_fits = asc.read(combine_flux_ascii) + combine_fits = asc.read(combine_flux_file) except FileNotFoundError: - log.warning(f"File not found! {combine_flux_ascii}") + log.warning(f"File not found! {combine_flux_file}") return Hgamma = combine_fits['HGAMMA_Flux_Observed'].data @@ -145,19 +138,20 @@ def OIII4363_flux_limit(combine_flux_ascii, verbose=False, log=None): return flux_limit -def movingaverage_box1D(values, width, boundary='fill', fill_value=0.0): +def movingaverage_box1D(values: np.ndarray, width: float, + boundary: str = 'fill', fill_value: float = 0.0)\ + -> np.ndarray: """ - Purpose: - Applies as boxcar kernel to smooth spectra + Applies as boxcar kernel to smooth spectra - :param values: numpy array containing the spectrum - :param width: float containing width for smoothing - :param boundary: handling of boundary values. + :param values: Array containing the spectrum + :param width: Width for smoothing + :param boundary: Handling of boundary values. Options are: 'None', 'fill', 'wrap', and 'extend' See astropy.convolution.convolve for more information - :param fill_value: float to indicate fill value for default boundary='fill' + :param fill_value: Indicate fill value for default boundary='fill' - :return smooth: numpy array contained the smoothed/convolved spectrum + :return: Array contained the smoothed/convolved spectrum """ box_kernel = Box1DKernel(width) diff --git a/Metallicity_Stack_Commons/analysis/ratios.py b/Metallicity_Stack_Commons/analysis/ratios.py index b8c1f58d..d3aaa967 100644 --- a/Metallicity_Stack_Commons/analysis/ratios.py +++ b/Metallicity_Stack_Commons/analysis/ratios.py @@ -1,3 +1,4 @@ +from logging import Logger import numpy as np from .. import line_name_short, OIII_r @@ -6,25 +7,22 @@ from ..logging import log_stdout, log_verbose -def flux_ratios(flux_dict, binned_data=False, get_R=True, verbose=False, - log=None): +def flux_ratios(flux_dict: dict, binned_data: bool = False, + get_R: bool = True, verbose: bool = False, + log: Logger = log_stdout()) -> dict: """ - Purpose: - Primary code to determine a variety of line ratios based on a dictionary - containing emission-line fluxes + Primary code to determine a variety of line ratios based on a dict + containing emission-line fluxes - :param flux_dict: dict containing line ratios - :param get_R: bool to indicate to populate with OIII4363/OIII5007 flux ratio - :param binned_data: bool for whether to analysis binned data. Default: False - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param flux_dict: Contains emission-line fluxes + :param get_R: Indicates populating OIII4363/OIII5007 flux ratio + :param binned_data: Whether to analyze binned data. Default: False + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return flux_ratios_dict: dict containing flux ratios + :return: Emission-line flux ratios """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) if not binned_data: diff --git a/Metallicity_Stack_Commons/analysis/temp_metallicity_calc.py b/Metallicity_Stack_Commons/analysis/temp_metallicity_calc.py index a46d1fb0..38b41673 100644 --- a/Metallicity_Stack_Commons/analysis/temp_metallicity_calc.py +++ b/Metallicity_Stack_Commons/analysis/temp_metallicity_calc.py @@ -1,3 +1,5 @@ +from logging import Logger +from typing import Union import numpy as np from .. import k_dict, OIII_r @@ -16,22 +18,22 @@ c = 0.98062 -def R_calculation(OIII4363, OIII5007, verbose=False, log=None): +def R_calculation(OIII4363: Union[float, np.ndarray], + OIII5007: Union[float, np.ndarray], + verbose: bool = False, log: Logger = log_stdout()) \ + -> Union[float, np.ndarray]: """ Computes the excitation flux ratio of [OIII]4363 to [OIII]5007. Adopts a 3.1-to-1 ratio for 5007/4959 - :param OIII4363: numpy array of OIII4363 fluxes - :param OIII5007: numpy array of OIII5007 fluxes - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param OIII4363: OIII4363 fluxes + :param OIII5007: OIII5007 fluxes + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return R_value: O++ excitation flux ratio + :return: O++ excitation flux ratio """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) R_value = OIII4363 / (OIII5007 * (1 + 1/OIII_r)) @@ -40,25 +42,24 @@ def R_calculation(OIII4363, OIII5007, verbose=False, log=None): return R_value -def temp_calculation(R, EBV=None, verbose=False, log=None): +def temp_calculation(R: np.ndarray, EBV: Union[None, np.ndarray] = None, + verbose: bool = False, + log: Logger = log_stdout()) -> np.ndarray: """ Computes electron temperature (T_e) from O++ excitation flux ratio Formula is: - T_e = a(-log(R)-b)^(-c) - where a = 13025, b=0.92506, and c=0.98062 (Nicholls et al. 2014) + T_e = a(-log(R)-b)^(-c) + where a = 13025, b=0.92506, and c=0.98062 (Nicholls et al. 2014) - :param R: numpy array of O++ excitation flux ratio (see R_calculation) - :param EBV: numpy array of E(B-V). Set to zero if not applying attenuation - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param R: Array of O++ excitation flux ratio (see R_calculation) + :param EBV: Array of E(B-V). Set to zero if not applying attenuation + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return T_e: numpy array of T_e (Kelvins) + :return: Array of T_e (Kelvins) """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) arr_shape = R.shape @@ -75,27 +76,30 @@ def temp_calculation(R, EBV=None, verbose=False, log=None): return T_e -def metallicity_calculation(T_e, TWO_BETA, THREE_BETA, EBV=None, det3=None, - verbose=False, log=None): +def metallicity_calculation(T_e: np.ndarray, TWO_BETA: np.ndarray, + THREE_BETA: np.ndarray, + EBV: Union[None, np.ndarray] = None, + det3: Union[None, np.ndarray] = None, + verbose: bool = False, + log: Logger = log_stdout()) -> dict: """ - Determines 12+log(O/H) from electron temperature and [OII]/Hb and [OIII]/Hb flux ratio + Determines 12+log(O/H) from electron temperature and [OII]/Hb and + [OIII]/Hb flux ratio - :param T_e: numpy array of temperature (see temp_calculation) - :param TWO_BETA: numpy array of [OII]/Hb flux ratio - :param THREE_BETA: numpy array of [OIII]/Hb flux ratio - :param EBV: Optional array input containing EBV distribution + :param T_e: Array of electron temperatures (see ``temp_calculation``) + :param TWO_BETA: Array of [OII]/Hb flux ratios + :param THREE_BETA: Array of [OIII]/Hb flux ratios + :param EBV: Optional array containing EBV distribution :param det3: Optional array to pass in to identify those satisfying det3 requirements. Default: None means full array is considered - Note: for MC inputs, a 1-D np.array index satisfying det3 - requirements will suffice - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object - :return metal_dict: dict containing 12+log(O/H), O+/H, O++/H, log(O+/H), log(O++/H) - """ + Note: for Monte Carlo inputs, a 1-D np.array index satisfying + det3 requirements will suffice + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - if log is None: - log = log_stdout() + :return: Contains 12+log(O/H), O+/H, O++/H, log(O+/H), log(O++/H) + """ log_verbose(log, "starting ...", verbose=verbose) diff --git a/Metallicity_Stack_Commons/column_names.py b/Metallicity_Stack_Commons/column_names.py index 9070b53b..e20e428b 100644 --- a/Metallicity_Stack_Commons/column_names.py +++ b/Metallicity_Stack_Commons/column_names.py @@ -6,15 +6,15 @@ # Need to define here -def line_fit_suffix_add(line_name0, line_type0): +def line_fit_suffix_add(line_name0: str, line_type0: str) -> list: """ - Purpose: - Simple list comprehension combining emission line fit suffixes with - the emission line. This works for individual lines + Simple list comprehension combining emission line fit suffixes with + the emission line. This works for individual lines + + :param line_name0: Line name + :param line_type0: Emission-line type (e.g., 'Balmer') - :param line_name0: str containing the line name - :param line_type0: str containing the emisison-line type (e.g., 'Balmer') - :return: gauss_lines_names: list with str formatted as [LINE]_[SUFFIX] + :return: List of strings formatted as [LINE]_[SUFFIX] """ gauss_lines_names = [f"{line_name0}_{suffix}" for suffix in gauss_names0] @@ -111,16 +111,16 @@ def line_fit_suffix_add(line_name0, line_type0): '.valid1.dustcorr.npz') -def merge_column_names(*args): +def merge_column_names(*args: list) -> list: """ - Purpose: - Merges multiple lists containing column names. + Merges multiple lists containing column names. Usage: column_names = merge_column_names(bin_names0, indv_names0) :param args: An undefined number of lists - :return merge_list: + + :return: Merged list """ merge_list = list() @@ -133,13 +133,15 @@ def merge_column_names(*args): return merge_list -def remove_from_list(list0, remove_entries): +def remove_from_list(list0: list, remove_entries: list) -> list: """ Purpose: - Remove entries from list + Remove entries from list of column names - :param list0: list of column names - :param remove_entries: list of column names to remove + :param list0: List of column names + :param remove_entries: List of column names to remove + + :return: List of column names after removal """ if py_vers == 3: @@ -153,23 +155,23 @@ def remove_from_list(list0, remove_entries): return dup_list0 -def indv_R23_O32(): +def indv_R23_O32() -> list: """ - Purpose: - Use remove_from_list() to provide simplified list that contains ID, logR23 and logO32 + Use remove_from_list() to provide simplified list that contains + ID, logR23 and logO32 - :return: list containing just ID, logR23, logO32 + :return: List containing just ID, logR23, logO32 """ return remove_from_list(indv_names0, ['logM', 'logLHb']) -def indv_M_LHb(): +def indv_M_LHb() -> list: """ - Purpose: - Use remove_from_list() to provide simplified list that contains ID, logM and logLHb + Use remove_from_list() to provide simplified list that contains + ID, logM and logLHb - :return: list containing just ID, logM, logLHb + :return: List containing just ID, logM, logLHb """ return remove_from_list(indv_names0, ['logR23', 'logO32']) diff --git a/Metallicity_Stack_Commons/logging.py b/Metallicity_Stack_Commons/logging.py index 60d3f8df..89afc580 100644 --- a/Metallicity_Stack_Commons/logging.py +++ b/Metallicity_Stack_Commons/logging.py @@ -8,7 +8,6 @@ import logging - log_format = '%(asctime)s %(levelname)7s - %(module)21s %(funcName)23s : %(message)s' formatter = logging.Formatter(log_format, "%H:%M:%S") file_formatter = logging.Formatter(log_format, "%H:%M:%S") @@ -16,24 +15,22 @@ class LogClass: """ - Purpose: - Main class to log information to stdout and ASCII logfile + Main class to log information to stdout and ASCII logfile Note: This code is identical to the one used in ReQUIAM: https://github.com/ualibraries/ReQUIAM To use: - log = LogClass(log_dir, logfile).get_logger() + log = LogClass(log_dir, logfile).get_logger() - Parameters: - log_dir: Relative path for exported logfile directory - logfile: Filename for exported log file + :param log_dir: Relative path for exported logfile directory + :param logfile: Filename for exported log file """ - def __init__(self, log_dir, logfile): + def __init__(self, log_dir: str, logfile: str): self.LOG_FILENAME = join(log_dir, logfile) - def get_logger(self): + def get_logger(self) -> logging.Logger: file_log_level = logging.DEBUG # This is for file logging log = logging.getLogger("main_logger") if not log.handlers: @@ -54,7 +51,10 @@ def get_logger(self): return log -def log_stdout(): +def log_stdout() -> logging.Logger: + """ + Returns stdout logging object + """ log_level = logging.INFO log = logging.getLogger("stdout_logger") if not log.handlers: @@ -68,11 +68,11 @@ def log_stdout(): return log -def get_user_hostname(): +def get_user_hostname() -> dict: """ - Purpose: - Retrieve user, hostname, IP, and OS configuration - :return sys_info: dictionary with 'user' 'hostname' and 'ip' dictionary + Retrieve user, hostname, IP, and OS configuration + + :return: Dictionary with 'user' 'hostname' and 'ip' keys """ sys_info = dict() @@ -87,15 +87,16 @@ def get_user_hostname(): return sys_info -def log_verbose(log, message, verbose=False): +def log_verbose(log: logging.Logger, + message: str, verbose: bool = False): """ - Purpose: - Log message depending on verbosity + Log message depending on verbosity - :param log: LogClass or logging object - :param message: str - :param verbose: bool to write verbose message to stdout. Default: file only + :param log: logging.Logger object + :param message: Message + :param verbose: Write verbose message to stdout. Default: file only """ + if verbose: log.info(message) # Write to stdout else: diff --git a/Metallicity_Stack_Commons/others/__init__.py b/Metallicity_Stack_Commons/others/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Metallicity_Stack_Commons/others/extract_deep2_data.py b/Metallicity_Stack_Commons/others/extract_deep2_data.py new file mode 100644 index 00000000..4b0bdc38 --- /dev/null +++ b/Metallicity_Stack_Commons/others/extract_deep2_data.py @@ -0,0 +1,75 @@ +from logging import Logger +from os.path import exists, join +from os import symlink +import numpy as np + +from astropy.io import fits +from astropy.table import Table + +from ..logging import log_stdout +from .. import line_name +from ..column_names import filename_dict + + +def main(infile: str, log: Logger = log_stdout()): + """ + Import previous DEEP2 Ly et al. (2015) dataset and export + an astropy Table called bin_fit.tbl + + :param infile: Input filename + :param log: logging.Logger object + """ + + log.info(f"Reading : {infile}") + orig_tab = fits.getdata(infile) + + gauss_cols = [str0 + '_Flux_Gaussian' for str0 in line_name] + obs_cols = [str0 + '_Flux_Observed' for str0 in line_name] + flux_rms_cols = [str0 + '_RMS' for str0 in line_name] + sigma_cols = [str0 + '_Sigma' for str0 in line_name] + snr_cols = [str0 + '_S/N' for str0 in line_name] + + # Column name in orig_table corresponding to gauss_cols + prefixes = ['OII', 'HD', 'HG', 'OIIIA', 'HB', 'OIIIB', 'OIIIR'] + orig_gauss_cols = [str0 + '_FLUX_MOD' for str0 in prefixes] + orig_obs_cols = [str0 + '_FLUX_DATA' for str0 in prefixes] + orig_sigma_cols = [str0 + '_SIGMA' for str0 in prefixes] + orig_snr_cols = [str0 + '_SNR' for str0 in prefixes] + + reformatted_tab = Table() + reformatted_tab['bin_ID'] = 1 + np.arange(len(orig_tab)) + + for ii in range(len(gauss_cols)): + flux = orig_tab[orig_gauss_cols[ii]] + rms = flux / orig_tab[orig_snr_cols[ii]] + # Widths are in observed frame, shift to rest-frame + gauss_sig = orig_tab[orig_sigma_cols[ii]] / (1+orig_tab['ZSPEC']) + reformatted_tab[gauss_cols[ii]] = flux + reformatted_tab[obs_cols[ii]] = orig_tab[orig_obs_cols[ii]] + reformatted_tab[flux_rms_cols[ii]] = rms + if 'OIII_4363' in sigma_cols[ii]: + reformatted_tab[sigma_cols[ii]] = gauss_sig + reformatted_tab[snr_cols[ii]] = orig_tab[orig_snr_cols[ii]] + + out_dir = "tests_data/DEEP2_Ly2015" + output_table = "DEEP2_Ly2015_fluxes.tbl" + out_file = join(out_dir, output_table) + log.info(f"Writing: {out_file}") + reformatted_tab.write(out_file, format='ascii.fixed_width_two_line', + overwrite=True) + + symlink_file = join(out_dir, filename_dict['bin_fit']) + if not exists(symlink_file): + symlink(output_table, symlink_file) + log.info(f"Symlink created to : {output_table}") + else: + log.info(f"Symlink exists: {symlink_file}") + + # Write bin_info file to use with valid_table module + info_tab = Table() + info_tab['bin_ID'] = 1 + np.arange(len(orig_tab)) + info_tab['N_stack'] = np.repeat(1, len(orig_tab)) + info_file = join(out_dir, filename_dict['bin_info']) + log.info(f"Writing: {info_file}") + info_tab.write(info_file, format='ascii.fixed_width_two_line', + overwrite=True) diff --git a/Metallicity_Stack_Commons/plotting/balmer.py b/Metallicity_Stack_Commons/plotting/balmer.py index a48fc815..32e66bc0 100644 --- a/Metallicity_Stack_Commons/plotting/balmer.py +++ b/Metallicity_Stack_Commons/plotting/balmer.py @@ -1,18 +1,22 @@ """ - balmer - ------ +balmer +------ - Generates plots illustrating Balmer recombination lines +Generates plots illustrating Balmer recombination lines - This code was created from: - https://github.com/astrochun/Zcalbase_gal/blob/master/Analysis/DEEP2_R23_O32/balmer_plots.py +This code was created from: + https://github.com/astrochun/Zcalbase_gal/blob/master/Analysis/DEEP2_R23_O32/balmer_plots.py """ +from logging import Logger from os.path import join +from typing import Union + import numpy as np import matplotlib.pyplot as plt from astropy.io import fits from astropy.io import ascii as asc +from astropy.table import Table from matplotlib.backends.backend_pdf import PdfPages from ..analysis.fitting import gauss, double_gauss @@ -26,25 +30,22 @@ n_cols = 3 -def extract_fit(astropy_table, line_name, balmer=False, verbose=False, - log=None): +def extract_fit(astropy_table: Table, line_name: str, balmer: bool = False, + verbose: bool = False, log: Logger = log_stdout()) \ + -> Union[None, dict]: """ - Purpose: - Extract best fit from table and fluxes, return a list of - fitting parameters and fluxes + Extract best fit from table and fluxes, return a list of + fitting parameters and fluxes :param astropy_table: Astropy table containing fitting result - :param line_name: line to extract fit results - :param balmer: boolean to indicate whether line is a Balmer line - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param line_name: Name of Line to extract fit results + :param balmer: Indicate whether line is a Balmer line + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return result_dict: dict of fitting results + :return: Fitting results """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) try: @@ -78,22 +79,23 @@ def extract_fit(astropy_table, line_name, balmer=False, verbose=False, return result_dict -def fitting_result(wave, y_norm, lambda_cen, line_fit, line_fit_neg, - flux_gauss, flux_spec, use_revised=False): +def fitting_result(wave: np.ndarray, y_norm: np.ndarray, lambda_cen: float, + line_fit: list, line_fit_neg: list, flux_gauss: float, + flux_spec: float, use_revised: bool = False) -> dict: """ - Purpose: - Returns fitting results based on inputs of best fit + Returns fitting results based on inputs of best fit - :param wave: numpy array of rest-frame wavelength + :param wave: Array of rest-frame wavelengths :param y_norm: Normalize 1-D spectra in units of 10^-17 erg/s/cm2/AA :param lambda_cen: Central wavelength in Angstroms - :param line_fit: list containing Balmer emission fits - :param line_fit_neg: list containing the absorption ("stellar") Balmer fit - :param flux_gauss: float containing flux from Gaussian model - :param flux_spec: float containing flux from spectrum (above median) - :param use_revised: bool to indicate whether fluxes have been revised. Default: False - - :return fit_dict: dict of fitting results + :param line_fit: List containing Balmer emission fits + :param line_fit_neg: List containing the absorption ("stellar") Balmer fit + :param flux_gauss: Flux from Gaussian model + :param flux_spec: Flux from spectrum (above median) + :param use_revised: Indicate whether fluxes have been revised. + Default: False + + :return: Dictionary of fitting results """ dx = wave[2] - wave[1] @@ -125,23 +127,20 @@ def fitting_result(wave, y_norm, lambda_cen, line_fit, line_fit_neg, # noinspection PyUnboundLocalVariable -def HbHgHd_fits(fitspath, out_pdf_prefix='HbHgHd_fits', - use_revised=False, verbose=False, log=None): +def HbHgHd_fits(fitspath: str, out_pdf_prefix: str ='HbHgHd_fits', + use_revised: bool = False, verbose: bool = False, + log: Logger = log_stdout()): """ - Purpose: - Generate PDF plots that illustrate H-delta, H-gamma, and H-beta line - profiles and best fit - - :param fitspath: full path (str) - :param out_pdf_prefix: Prefix for outpute PDF file (str) - :param use_revised: Indicate whether to use regular or revised tables (bool) - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + Generate PDF plots that illustrate H-delta, H-gamma, and H-beta line + profiles and best fit + + :param fitspath: Full path + :param out_pdf_prefix: Prefix for output PDF file + :param use_revised: Indicate whether to use regular or revised tables + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) comp_spec_file = join(fitspath, filename_dict['comp_spec']) diff --git a/Metallicity_Stack_Commons/update_det4363_info.py b/Metallicity_Stack_Commons/update_det4363_info.py index 158a5393..731a64d1 100644 --- a/Metallicity_Stack_Commons/update_det4363_info.py +++ b/Metallicity_Stack_Commons/update_det4363_info.py @@ -1,27 +1,29 @@ +from logging import Logger +from typing import Tuple +import numpy as np + from chun_codes import match_nosort +from astropy.table import Table + from .logging import log_stdout, log_verbose -def get_index(det4363_table, input_table, column_name, verbose=False, - log=None): +def get_index(det4363_table: Table, input_table: Table, column_name: str, + verbose: bool = False, log: Logger = log_stdout()) -> \ + Tuple[np.ndarray, np.ndarray]: """ - Purpose: - Uses either OBJNO or AP/SLIT info to get index for an existing table + Uses either OBJNO or AP/SLIT info to get index for an existing table - :param det4363_table: astropy table containing DEEP2 [OIII]4363-detected sample - :param input_table: astropy table containing the entire sample to be updated - :param column_name: str containing column for cross-matching - :param verbose: bool to write verbose message to stdout. Default: file only - :param log: LogClass or logging object + :param det4363_table: Astropy table containing DEEP2 [OIII]4363-detected sample + :param input_table: Astropy table containing the entire sample to be updated + :param column_name: Column name for cross-matching + :param verbose: Write verbose message to stdout. Default: file only + :param log: logging.Logger object - :return det4363_idx: Numpy index arrays containing for det4363_table and input_table - :return input_idx: numpy index array for input + :return: Index arrays for ``det4363_table``, ``input_table`` """ - if log is None: - log = log_stdout() - log_verbose(log, "starting ...", verbose=verbose) if column_name != 'OBJNO' or column_name != 'SLIT' or column_name != 'AP': diff --git a/Metallicity_Stack_Commons/valid_table.py b/Metallicity_Stack_Commons/valid_table.py index e13c0629..ecd687de 100644 --- a/Metallicity_Stack_Commons/valid_table.py +++ b/Metallicity_Stack_Commons/valid_table.py @@ -6,34 +6,26 @@ from .column_names import filename_dict, valid_table_names0 # , bin_names0, remove_from_list -def make_validation_table(fitspath): +def make_validation_table(fitspath: str): """ - Purpose: - This function creates a validation table for a given binning set. The validation table - contains a OIII4363 detection column where 1.0 means detection, 0.5 means non-detection with - reliable OIII5007, and 0.0 means unreliable non-detection. - This function will be run every time the analysis is completed and will create a validation - table for every analysis. + This function creates a validation table for a given binning set. + The validation table contains a OIII4363 detection column where 1.0 + means detection, 0.5 means non-detection with reliable OIII5007, and + 0.0 means unreliable non-detection. This function will be run every + time the analysis is completed and will create a validation table + for every analysis. Usage: valid_table.make_validation_table(fitspath, bin_type_str) - Params: - fitspath --> a string of the file path where the input file is and where the output file - will be placed. - not in use: - bin_type_str --> a string describing the binning type. (e.g. 'massLHbetabin' or 'massbin') - --> This is dataset for Zcalbase_gal analysis - - Returns: - None + :param fitspath: Full file path where the input file is and where the + output file will be placed. Outputs: - fitspath + 'bin_validation.tbl' --> a validation table containing bin IDs; - number of galaxies in each bin; and - column indicating OIII4363 detection/non-detection - OIII4363_Flux_Observed - OIII4363_S/N + fitspath + 'bin_validation.tbl' + Validation table containing bin IDs; number of galaxies in each bin; + and column indicating OIII4363 detection/non-detection, + OIII4363_Flux_Observed, OIII4363_S/N """ bin_table = asc.read(fitspath + filename_dict['bin_info']) @@ -88,33 +80,27 @@ def make_validation_table(fitspath): ''' -def compare_to_by_eye(fitspath, dataset): +def compare_to_by_eye(fitspath: str, dataset: str): """ - Purpose -> This function takes the automated validation table and checks it against - inputted measurement that are determined by eye. These inputted measurements - are in the np.where statements. It outputs a revised validation table based - on the inputted measurements. - - Usage -> valid_table.make_validation_table(fitspath, dataset) + This function takes the automated validation table and checks it against + inputted measurement that are determined by eye. These inputted + measurements are in the np.where statements. It outputs a revised + validation table based on the inputted measurements. - Params: - fitspath --> a string of the file path where the input file is and where the output file - will be placed - dataset --> a string that is used to determine which eye measurements to use + Usage: + valid_table.make_validation_table(fitspath, dataset) - Returns: - None + :param fitspath: Full file path where the input file is and where the + output file will be placed. + :param dataset: Determine which eye measurements to use Outputs: - fitspath + 'bin_validation_revised.tbl' and '.csv' --> - a validation table containing bin IDs; - number of galaxies in each bin; and - column indicating OIII4363 detection/non-detection - OIII4363_Flux_Observed - OIII4363_S/N - Notes - + fitspath + 'bin_validation_revised.tbl' and '.csv' + Validation table containing bin IDs; number of galaxies in each bin; + and column indicating OIII4363 detection/non-detection, + OIII4363_Flux_Observed, OIII4363_S/N, Notes """ + ver_table = fitspath + filename_dict['bin_valid'] ver_tab = asc.read(ver_table) indicate = ver_tab['Detection'] diff --git a/README.md b/README.md index 21adf406..099c6abe 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Metallicity_Stack_Commons Set of common codes used in metallicity studies that use the stacking techniques -[![GitHub build](https://github.com/astrochun/Metallicity_Stack_Commons/workflows/Python%20package/badge.svg?)](https://github.com/astrochun/Metallicity_Stack_Commons/actions?query=workflow%3A%22Python+package%22) +[![GitHub Workflow Status (master)](https://img.shields.io/github/workflow/status/astrochun/Metallicity_Stack_Commons/Python%20package/master?color=blue&label=build%20%28master%29&logo=github)](https://github.com/astrochun/Metallicity_Stack_Commons/actions?query=workflow%3A%22Python+package%22+branch%3Amaster) +[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/astrochun/Metallicity_Stack_Commons/Python%20package?color=blue&label=build%20%28latest%29&logo=github)](https://github.com/astrochun/Metallicity_Stack_Commons/actions?query=workflow%3A%22Python+package%22) +[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/astrochun/Metallicity_Stack_Commons/Sphinx%20Docs%20Check?label=docs&color=blue)](https://github.com/astrochun/Metallicity_Stack_Commons/actions?query=workflow%3A%22Sphinx+Docs+Check%22) ![GitHub top language](https://img.shields.io/github/languages/top/astrochun/Metallicity_Stack_Commons) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/astrochun/Metallicity_Stack_Commons) ![GitHub](https://img.shields.io/github/license/astrochun/Metallicity_Stack_Commons?color=blue) \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..9534b018 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..4eaec8a9 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,3 @@ +sphinx>=3.0 +sphinx-rtd-theme==0.5.1 +sphinx-autodoc-typehints==1.11.1 diff --git a/docs/source/Metallicity_Stack_Commons.analysis.rst b/docs/source/Metallicity_Stack_Commons.analysis.rst new file mode 100644 index 00000000..bfb0925c --- /dev/null +++ b/docs/source/Metallicity_Stack_Commons.analysis.rst @@ -0,0 +1,61 @@ +``analysis`` subpackage +======================= + +Submodules +---------- + +Metallicity\_Stack\_Commons.analysis.attenuation module +------------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.analysis.attenuation + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.analysis.composite\_indv\_detect module +------------------------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.analysis.composite_indv_detect + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.analysis.error\_prop module +------------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.analysis.error_prop + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.analysis.fitting module +--------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.analysis.fitting + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.analysis.ratios module +-------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.analysis.ratios + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.analysis.temp\_metallicity\_calc module +------------------------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.analysis.temp_metallicity_calc + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: Metallicity_Stack_Commons.analysis + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/Metallicity_Stack_Commons.others.rst b/docs/source/Metallicity_Stack_Commons.others.rst new file mode 100644 index 00000000..c5bb33e4 --- /dev/null +++ b/docs/source/Metallicity_Stack_Commons.others.rst @@ -0,0 +1,21 @@ +``others`` subpackage +===================== + +Submodules +---------- + +Metallicity\_Stack\_Commons.others.extract\_deep2\_data module +-------------------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.others.extract_deep2_data + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: Metallicity_Stack_Commons.others + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/Metallicity_Stack_Commons.plotting.rst b/docs/source/Metallicity_Stack_Commons.plotting.rst new file mode 100644 index 00000000..25642bd4 --- /dev/null +++ b/docs/source/Metallicity_Stack_Commons.plotting.rst @@ -0,0 +1,21 @@ +``plotting`` subpackage +======================= + +Submodules +---------- + +Metallicity\_Stack\_Commons.plotting.balmer module +-------------------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.plotting.balmer + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: Metallicity_Stack_Commons.plotting + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/Metallicity_Stack_Commons.rst b/docs/source/Metallicity_Stack_Commons.rst new file mode 100644 index 00000000..c94b36e1 --- /dev/null +++ b/docs/source/Metallicity_Stack_Commons.rst @@ -0,0 +1,29 @@ +Metallicity\_Stack\_Commons package +=================================== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + Metallicity_Stack_Commons.analysis + Metallicity_Stack_Commons.others + Metallicity_Stack_Commons.plotting + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + Metallicity_Stack_Commons.submodules + + +Common functions +---------------- + +.. automodule:: Metallicity_Stack_Commons + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/Metallicity_Stack_Commons.submodules.rst b/docs/source/Metallicity_Stack_Commons.submodules.rst new file mode 100644 index 00000000..472c05ab --- /dev/null +++ b/docs/source/Metallicity_Stack_Commons.submodules.rst @@ -0,0 +1,31 @@ +Metallicity\_Stack\_Commons.column\_names module +------------------------------------------------ + +.. automodule:: Metallicity_Stack_Commons.column_names + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.logging module +------------------------------------------ + +.. automodule:: Metallicity_Stack_Commons.logging + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.update\_det4363\_info module +-------------------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.update_det4363_info + :members: + :undoc-members: + :show-inheritance: + +Metallicity\_Stack\_Commons.valid\_table module +----------------------------------------------- + +.. automodule:: Metallicity_Stack_Commons.valid_table + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..07af3d5b --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,60 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +import sphinx_rtd_theme +import sphinx_autodoc_typehints + +sys.path.insert(0, os.path.abspath('../../')) + +# -- Project information ----------------------------------------------------- + +project = 'metallicity-stack-commons' +copyright = '2021, Chun Ly, Reagen Leimbach, and Caroline McCormick' +author = 'Chun Ly, Reagen Leimbach, and Caroline McCormick' + +# The full version, including alpha/beta/rc tags +release = '1.3.1' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx_rtd_theme", + "sphinx.ext.autodoc", + "sphinx_autodoc_typehints", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..d33ae32a --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,21 @@ +.. metallicity-stack-commons documentation master file, created by + sphinx-quickstart on Sat Feb 6 23:30:49 2021. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to metallicity-stack-commons's documentation! +===================================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + intro.rst + modules.rst + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/intro.rst b/docs/source/intro.rst new file mode 100644 index 00000000..7bc25d50 --- /dev/null +++ b/docs/source/intro.rst @@ -0,0 +1,18 @@ +Metallicity_Stack_Commons +========================= + +Set of common codes used in metallicity studies that use the stacking +techniques + +|GitHub build (master)| |GitHub build| |docs| +|GitHub top language| |GitHub release (latest by date)| |GitHub| + +.. |GitHub build (master)| image:: https://img.shields.io/github/workflow/status/astrochun/Metallicity_Stack_Commons/Python%20package/master?color=blue&label=build%20%28master%29&logo=github + :target: https://github.com/astrochun/Metallicity_Stack_Commons/actions?query=workflow%3A%22Python+package%22+branch%3Amaster +.. |GitHub build| image:: https://img.shields.io/github/workflow/status/astrochun/Metallicity_Stack_Commons/Python%20package?color=blue&label=build%20%28latest%29&logo=github + :target: https://github.com/astrochun/Metallicity_Stack_Commons/actions?query=workflow%3A%22Python+package%22 +.. |docs| image:: https://img.shields.io/github/workflow/status/astrochun/Metallicity_Stack_Commons/Sphinx%20Docs%20Check?label=docs&color=blue + :target: https://github.com/astrochun/Metallicity_Stack_Commons/actions?query=workflow%3A%22Sphinx+Docs+Check%22 +.. |GitHub top language| image:: https://img.shields.io/github/languages/top/astrochun/Metallicity_Stack_Commons +.. |GitHub release (latest by date)| image:: https://img.shields.io/github/v/release/astrochun/Metallicity_Stack_Commons +.. |GitHub| image:: https://img.shields.io/github/license/astrochun/Metallicity_Stack_Commons?color=blue \ No newline at end of file diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 00000000..b2dfd94e --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,7 @@ +API Documentation +================= + +.. toctree:: + :maxdepth: 4 + + Metallicity_Stack_Commons diff --git a/setup.py b/setup.py index bd53fab4..ecabea5f 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='Metallicity_Stack_Commons', - version='1.3.1', + version='1.4.0', packages=['Metallicity_Stack_Commons'], url='https://github.com/astrochun/Metallicity_Stack_Commons', license='MIT License', diff --git a/tests/test_attenuation.py b/tests/test_attenuation.py index a7e399ee..4dea3175 100644 --- a/tests/test_attenuation.py +++ b/tests/test_attenuation.py @@ -5,9 +5,19 @@ from Metallicity_Stack_Commons import line_name_short from chun_codes import random_pdf +import pytest + def test_compute_EBV(): + # Test Error handling when list is provided + with pytest.raises(TypeError): + attenuation.compute_EBV([0.45, 0.38], verbose=True) + + # Test Error handling when source is incorrect + with pytest.raises(KeyError): + attenuation.compute_EBV(0.45, source='test', verbose=True) + dx = 0.05 # This is for randomization offsets = [0, -0.01, 0.01] diff --git a/tests/test_error_prop.py b/tests/test_error_prop.py new file mode 100644 index 00000000..220232e7 --- /dev/null +++ b/tests/test_error_prop.py @@ -0,0 +1,38 @@ +from Metallicity_Stack_Commons.analysis import error_prop + +deep2_dir = 'tests_data/DEEP2_Ly2015/' + + +def test_fluxes_derived_prop(): + + # Even though these are individual galaxies, we can trick it to think + # it's binned data. + params_list = [ + {'raw': True, # No MC, no dust, use default valid_table + 'apply_dust': False, + 'revised': False}, + {'raw': True, # No MC, no dust, use revised valid_table + 'apply_dust': False, + 'revised': True}, + {'raw': True, # No MC, apply dust, use default valid_table + 'apply_dust': True, + 'revised': False}, + {'raw': True, # No MC, apply dust, use revised valid_table + 'apply_dust': True, + 'revised': True}, + {'raw': False, # MC, no dust, use default valid_table + 'apply_dust': False, + 'revised': False}, + {'raw': False, # MC, no dust, use revised valid_table + 'apply_dust': False, + 'revised': True}, + {'raw': False, # MC, apply dust, use default valid_table + 'apply_dust': True, + 'revised': False}, + {'raw': False, # MC, apply dust, use revised valid_table + 'apply_dust': True, + 'revised': True}, + ] + for params in params_list: + error_prop.fluxes_derived_prop(deep2_dir, **params, binned_data=True, + verbose=True) diff --git a/tests/test_valid_table.py b/tests/test_valid_table.py new file mode 100644 index 00000000..b0ce4222 --- /dev/null +++ b/tests/test_valid_table.py @@ -0,0 +1,8 @@ +from Metallicity_Stack_Commons import valid_table + +deep2_dir = 'tests_data/DEEP2_Ly2015/' + + +def test_valid_table(): + + valid_table.make_validation_table(deep2_dir) diff --git a/tests_data/DEEP2_Ly2015/DEEP2_Ly2015_fluxes.tbl b/tests_data/DEEP2_Ly2015/DEEP2_Ly2015_fluxes.tbl new file mode 100644 index 00000000..5649ec58 --- /dev/null +++ b/tests_data/DEEP2_Ly2015/DEEP2_Ly2015_fluxes.tbl @@ -0,0 +1,30 @@ +bin_ID OII_3727_Flux_Gaussian OII_3727_Flux_Observed OII_3727_RMS OII_3727_S/N HDELTA_Flux_Gaussian HDELTA_Flux_Observed HDELTA_RMS HDELTA_S/N HGAMMA_Flux_Gaussian HGAMMA_Flux_Observed HGAMMA_RMS HGAMMA_S/N OIII_4363_Flux_Gaussian OIII_4363_Flux_Observed OIII_4363_RMS OIII_4363_Sigma OIII_4363_S/N HBETA_Flux_Gaussian HBETA_Flux_Observed HBETA_RMS HBETA_S/N OIII_4958_Flux_Gaussian OIII_4958_Flux_Observed OIII_4958_RMS OIII_4958_S/N OIII_5007_Flux_Gaussian OIII_5007_Flux_Observed OIII_5007_RMS OIII_5007_S/N +------ ---------------------- ---------------------- ---------------------- ------------ ---------------------- ---------------------- ---------------------- ---------- ---------------------- ---------------------- ---------------------- ---------- ----------------------- ----------------------- ---------------------- --------------- ------------- ---------------------- ---------------------- ---------------------- --------- ----------------------- ----------------------- ---------------------- ------------- ----------------------- ----------------------- ---------------------- ------------- + 1 1.4611654506337622e-16 1.3811001906901415e-16 1.8340070927358696e-18 79.670654 1.490492357056484e-17 1.467771096031317e-17 1.1480772219569343e-18 12.98251 3.1737357360313744e-17 3.4106862451410266e-17 1.2589114166407038e-18 25.21016 6.011975951763881e-18 6.936906146839537e-18 1.2180469759734307e-18 1.2723644 4.9357505 6.692077318982134e-17 6.612057588168625e-17 1.2710347754316497e-18 52.650623 9.577582952108365e-17 9.52662198929851e-17 1.1235604369991807e-18 85.24315 2.746208949635402e-16 2.7780245020329256e-16 1.195924252912974e-18 229.63068 + 2 7.763706794674884e-17 7.70406045506491e-17 2.1625351125962033e-18 35.90095 1.0750266051522672e-17 1.0573352976621818e-17 1.5292576640956627e-18 7.0297284 1.2045434909450857e-17 1.7670966303639575e-17 1.0140043640907864e-18 11.879076 4.517188237782733e-18 6.690768462851853e-18 7.637094810491333e-19 0.34752208 5.914799 5.108661806133284e-17 5.0669072107901944e-17 1.5564922993983999e-18 32.821632 9.475296669065002e-17 9.304307061346374e-17 2.0429631176636436e-18 46.380165 2.9930589852914417e-16 3.017179220165109e-16 1.7931290621070073e-18 166.91821 + 3 1.0809142288122797e-16 1.1357127606371006e-16 2.491862172752992e-18 43.37777 1.2538771657380437e-17 1.2337123278433036e-17 1.4577793732155199e-18 8.601282 2.1914992306512557e-17 2.069595346874434e-17 1.1482437098553138e-18 19.085663 3.785567315318562e-18 3.7042160815368825e-18 1.0331696323883744e-18 0.56998765 3.6640327 4.530725050888783e-17 4.514547523545016e-17 1.1694582542448424e-18 38.742085 6.139354390118641e-17 6.029512482942245e-17 1.148464779643252e-18 53.457054 1.7633573225364037e-16 1.7500262221895214e-16 1.390938504406324e-18 126.77464 + 4 3.291895280447067e-17 3.054742929700359e-17 2.795189234366684e-18 11.777003 1.352772475226144e-17 1.2221708622877367e-17 3.3079810091228244e-18 4.0894203 2.4977129490174207e-17 2.3913237166632197e-17 2.985268979640074e-18 8.366794 1.3294461489725875e-17 1.3092024823934616e-17 2.4378528452104013e-18 0.91865677 5.4533486 3.748552433469182e-17 3.6923698257957295e-17 2.489636043937736e-18 15.056628 6.501478418320847e-17 6.369050616808794e-17 1.85516356899267e-18 35.04531 2.0251539506701206e-16 2.0280328723594753e-16 1.826512620755435e-18 110.87544 + 5 2.224032969084139e-16 2.2339932824504615e-16 1.2579593259975772e-18 176.79689 3.703975201693692e-17 3.696643967766954e-17 9.760514162940783e-19 37.948566 7.326875504754261e-17 7.056386264644673e-17 1.1560109383491198e-18 63.380676 1.363427188499347e-17 1.2753365398246719e-17 1.3635455229286937e-18 0.890556 9.999132 1.9667418939469824e-16 1.9616137882344575e-16 1.5073089120272506e-18 130.48035 4.171190550060094e-16 4.152146873285342e-16 1.4435198915700607e-18 288.9597 1.2568327158819523e-15 1.2569678625995611e-15 1.4734224952529661e-18 853.00226 + 6 2.3047962371158565e-16 2.3256523058596255e-16 1.756347636654408e-18 131.22665 2.536315372364372e-17 2.5236766404944803e-17 1.1772025091746955e-18 21.545277 4.805707911962796e-17 4.765490608080517e-17 1.1012335414289475e-18 43.639317 4.223469319074743e-18 3.9825209681568884e-18 8.366726022791214e-19 0.40366855 5.0479355 1.13898209610508e-16 1.1239507953279275e-16 1.4083202227662495e-18 80.87522 1.7422229301402976e-16 1.718720422277164e-16 1.1654573885212553e-18 149.48834 5.365502928606332e-16 5.31499494084988e-16 1.2106436391236597e-18 443.19424 + 7 3.2793285540578144e-16 3.2752781483831627e-16 2.194588942515675e-18 149.42792 2.8422339544358815e-17 2.7955845155340904e-17 1.3427384901914927e-18 21.167442 3.97334512931784e-17 5.86361800411569e-17 1.1410190384222828e-18 34.822777 5.969577825228504e-18 5.754788289471245e-18 1.760766712922927e-18 1.0919118 3.3903286 1.2894037556538503e-16 1.2808739471393596e-16 1.5911726196141041e-18 81.03481 1.643581138751702e-16 1.6562428578449617e-16 1.4899111984950018e-18 110.31403 4.790804298496822e-16 4.803595821789945e-16 1.4473893137767577e-18 330.99625 + 8 3.5236415095823734e-17 3.446075790926541e-17 1.5813789627936754e-18 22.282082 99.9990005493164 99.9990005493164 inf 0.0 9.413966614501117e-18 9.582355302325552e-18 9.498213328985872e-19 9.911303 6.6041776656394825e-18 5.248943432691962e-18 1.6707677263604966e-18 1.3179108 3.9527802 2.6145684865459484e-17 2.6979196900358793e-17 1.3133452335298314e-18 19.907701 4.857934444922665e-17 4.845592071194303e-17 1.2266390329911373e-18 39.60362 1.6351686511168403e-16 1.5665431086816113e-16 1.2882721453256705e-18 126.92727 + 9 1.594267016825221e-16 1.5486852622577108e-16 1.8738847571720613e-18 85.07818 1.597289583507632e-17 1.61444572685084e-17 1.084782619066111e-18 14.724513 3.00232163284108e-17 2.952113608055733e-17 1.1487078099628728e-18 26.136513 3.746146210604035e-18 3.415297994662249e-18 1.0542827116307672e-18 0.5869104 3.5532653 6.484305704611048e-17 6.36016344160058e-17 1.4596423558328086e-18 44.423935 9.512233425388221e-17 9.58023519146704e-17 1.2265952485508408e-18 77.5499 2.6229940246265257e-16 2.6088028781416308e-16 1.2552368837678662e-18 208.96407 + 10 1.956149667441004e-16 1.9270658647547415e-16 1.2719780117935786e-18 153.78801 2.806482720598263e-17 2.78361279568135e-17 9.128178947264401e-19 30.745264 5.249037796148838e-17 5.1465113957260994e-17 9.919415523350039e-19 52.916805 8.275537379930646e-18 8.364974931074022e-18 1.2867316710984539e-18 1.1015339 6.43144 1.3033151884429882e-16 1.2913497744866242e-16 1.3439483182729123e-18 96.976585 2.229588588417749e-16 2.236165372277603e-16 1.1753453097659802e-18 189.69647 6.577086524497556e-16 6.437660026422937e-16 1.1495600151757855e-18 572.13947 + 11 1.130867996876602e-16 1.0467469711279603e-16 1.470058342957938e-18 76.92674 1.713060854007589e-17 1.692276875760292e-17 9.759540683034446e-19 17.55268 2.5880897915885672e-17 2.5899156550277183e-17 8.895039146516838e-19 29.095879 7.211742339872157e-18 6.793400645597635e-18 9.34241269265026e-19 0.5398601 7.7193575 5.4569225742437707e-17 5.4049320838910423e-17 1.0220383197002394e-18 53.392544 1.0848597330997548e-16 1.0815837079487172e-16 8.707555825757382e-19 124.58832 3.013328074179466e-16 3.0100324341161996e-16 8.433360322736571e-19 357.3105 + 12 1.3596868007368588e-16 1.3570891889156463e-16 1.8856451586218314e-18 72.10725 2.2208041568136574e-17 2.2269875830462382e-17 1.0333468910936308e-18 21.491371 3.599681764919238e-17 3.54981419940536e-17 1.1262137010144603e-18 31.962688 6.8295544086724345e-18 1.0895289625862764e-17 5.168565787428478e-19 0.4056755 13.213635 7.907985826656316e-17 7.911238685745104e-17 1.1634830493457559e-18 67.96821 1.3551446963356772e-16 1.3197025108560408e-16 1.1156524826892878e-18 121.46656 3.7081360451895084e-16 3.6587186612609497e-16 1.0378955080503207e-18 357.2745 + 13 9.272015716872657e-17 9.011138833541193e-17 8.934903614053951e-19 103.77298 8.8133480736943e-18 8.959319544962596e-18 5.906577407371284e-19 14.921244 1.7101270042586708e-17 1.8199790510145962e-17 6.740096155162572e-19 25.372442 2.8102046612587983e-18 2.9376194276732592e-18 5.368580476895696e-19 0.35912392 5.2345395 4.083550545121145e-17 4.053868370524812e-17 8.1420287206117565e-19 50.15397 6.766819595514946e-17 6.785290365996992e-17 7.974064286262508e-19 84.86036 1.8839290531692227e-16 1.8838548233029777e-16 7.860092300870029e-19 239.68282 + 14 2.8966697734326594e-16 2.9137197525675004e-16 1.0147943068568577e-18 285.44403 3.994135146193141e-17 4.05982846201983e-17 7.176460074913828e-19 55.656063 7.208948861028144e-17 6.820163198171387e-17 1.1854771819744604e-18 60.810524 1.0172789246569983e-17 9.469657692776971e-18 1.0911672931009937e-18 0.9182202 9.32285 1.7026283624223047e-16 1.6994512096285482e-16 9.133975040553018e-19 186.40607 3.1206707823087016e-16 3.119928821575693e-16 8.696393252398954e-19 358.84656 9.151491615343556e-16 9.151029732422795e-16 9.211906518863142e-19 993.44165 + 15 7.691597821083942e-17 7.651150012619079e-17 1.3105786302244829e-18 58.688564 2.2822788140948663e-17 2.2581784413987957e-17 8.533461760634949e-19 26.745052 4.1989848685544753e-17 4.933260567977456e-17 7.102248323493068e-19 59.12191 9.883726604724067e-18 1.1962008793230175e-17 7.288313704680116e-19 0.71919054 13.561061 1.2496531717163617e-16 1.2523327381893833e-16 1.1704675653785232e-18 106.7653 2.3032809788750025e-16 2.308128584822353e-16 1.302470469057076e-18 176.8394 7.001463696345751e-16 6.981180052727911e-16 1.1733154882633532e-18 596.72473 + 16 1.8097799918752967e-16 1.84258994543609e-16 2.1077687965540793e-18 85.86236 1.013878684571124e-17 1.0074624741265345e-17 1.8084513258149394e-18 5.6063366 3.656555499714701e-17 3.540129810281895e-17 2.0585052136569166e-18 17.763159 6.598781442324649e-18 6.774770798001975e-18 1.9392942562390203e-18 1.2951453 3.4026716 9.218353749281861e-17 8.700639523175311e-17 2.7097160175425773e-18 34.01963 1.050167514306728e-16 1.0350794418600263e-16 2.2659115650823075e-18 46.34636 2.9309101667761587e-16 2.8651672785584827e-16 2.2532376625682942e-18 130.0755 + 17 1.366382463836006e-16 1.37805126912672e-16 1.7315862205183818e-18 78.909294 1.4999851215355783e-17 1.477801923651466e-17 1.2162356891395464e-18 12.333014 2.6031041350328394e-17 3.319184947405491e-17 9.005966693630249e-19 28.904217 4.129023758636379e-18 4.637125106677875e-18 9.610255960216256e-19 0.8686015 4.2964764 7.308816854096799e-17 7.134606411649417e-17 1.3840564450365697e-18 52.807217 1.1924997876924477e-16 1.1776596609746847e-16 1.3724814310419574e-18 86.886406 3.5906239839720304e-16 3.551084264532163e-16 1.3332126932585984e-18 269.32117 + 18 1.126857163522455e-16 1.180816338636106e-16 1.81777225953256e-18 61.991108 1.8041303699808875e-17 1.8187696629830617e-17 1.2126950698427444e-18 14.877032 3.732179555704385e-17 3.5308042477735007e-17 1.2133318982020559e-18 30.759758 4.189534572606061e-18 4.291230911009648e-18 9.478229002703356e-19 0.5502453 4.420166 9.405387874877402e-17 9.298134825968678e-17 1.4892582080344472e-18 63.15485 1.6706145685587607e-16 1.6557578212118122e-16 1.5386143423755065e-18 108.57916 4.932660667339579e-16 4.679462145268091e-16 1.6697786869284846e-18 295.40805 + 19 2.4008849781413644e-16 2.4682127154428525e-16 2.19090939939824e-18 109.58395 1.9401474229882582e-17 3.762841932261292e-17 8.033953872379115e-19 24.149347 8.757405041289352e-17 8.422583446751124e-17 2.090693243489599e-18 41.887566 9.011296528488667e-18 7.41170466916978e-18 1.7243896390685245e-18 0.5168211 5.225789 1.469455480749291e-16 1.45085619118594e-16 1.9908125900446697e-18 73.811844 3.065311265259854e-16 3.0699086957109995e-16 2.1560340890133577e-18 142.1736 8.620231186200384e-16 8.668933786039037e-16 2.1719255478023075e-18 396.8935 + 20 1.0291284211272748e-16 1.0641857251507012e-16 2.103152944696418e-18 48.932648 99.9990005493164 99.9990005493164 inf 0.0 2.7725122284518018e-17 2.7685508524584027e-17 1.3012010830286102e-18 21.307331 7.611225357652905e-18 7.734628766400586e-18 1.8432651480843126e-18 1.4817669 4.129208 6.721329355638883e-17 6.8192368496675e-17 1.5713180436698157e-18 42.775105 9.506110101436157e-17 9.597745345825717e-17 1.2532033143058417e-18 75.85449 2.783977840726885e-16 2.7845466132756e-16 1.3414351786257463e-18 207.53726 + 21 9.424575615096017e-17 8.900632797660029e-17 2.511859011584736e-18 37.52032 1.7941163445060814e-17 1.8347094730957938e-17 1.3883540365412218e-18 12.922614 2.5593227601785726e-17 2.4650048232116795e-17 1.6334671541201554e-18 15.668039 6.7140582365311995e-18 6.620468272154165e-18 1.35215937537948e-18 0.42182016 4.965434 5.720604975103787e-17 5.579915855355239e-17 1.7550639274456475e-18 32.594852 1.0627229453164901e-16 1.0562912322527381e-16 1.5572534468740333e-18 68.243416 2.93185551076082e-16 3.010835051451806e-16 1.521318720206052e-18 192.71803 + 22 1.1096391012871431e-16 1.1333505975054452e-16 2.5034570164800797e-18 44.324272 1.9940052266520382e-17 1.963296525227467e-17 1.7274228261307228e-18 11.543238 2.918048686559326e-17 2.7728902332786747e-17 1.3476520878671559e-18 21.652834 6.421924804473403e-18 6.24520023978129e-18 1.2231225679389965e-18 0.41531453 5.2504344 6.455841281932542e-17 6.364823058504402e-17 1.5771394531257522e-18 40.933865 1.1074773139429592e-16 1.131033946479515e-16 1.5383795797321129e-18 71.98986 3.4493854177030687e-16 3.3398721622765353e-16 1.6145038554057877e-18 213.64987 + 23 1.1647917987630348e-16 1.186757613016605e-16 1.3697637220101115e-18 85.035965 1.6535252369319254e-17 1.6594690297600607e-17 7.915322847424707e-19 20.89018 3.0361473953503195e-17 3.341792560691393e-17 1.0286344682816773e-18 29.51629 4.105041095939157e-18 3.196077715577586e-18 1.2757138256196946e-18 0.5624932 3.2178385 7.811728466457745e-17 7.673590777152517e-17 1.3641768205805725e-18 57.263313 1.5194007330559932e-16 1.493945512838955e-16 1.224518525551742e-18 124.08148 4.457800366258388e-16 4.3968342759322196e-16 1.2586184210716973e-18 354.18204 + 24 1.7298375517090279e-16 1.7142313667025614e-16 1.5011457720947936e-18 115.23448 3.095076610390343e-17 3.0597861761074616e-17 9.150417001104403e-19 33.824432 6.24203177228406e-17 6.199265664184162e-17 1.146610470720663e-18 54.43899 9.691944862886775e-18 9.603446777561852e-18 1.01461832201494e-18 0.50275433 9.552306 1.504183544533348e-16 1.4885941345028053e-16 1.1752083285467663e-18 127.99293 2.7217833142446583e-16 2.706519737442124e-16 1.1980995836844266e-18 227.17505 7.969449366473857e-16 7.766815446627793e-16 1.3044410583977631e-18 610.94745 + 25 6.46470236072161e-17 6.512414800198158e-17 1.1374075863970708e-18 56.837166 1.1473371539132727e-17 1.1383009836338071e-17 9.768325592353997e-19 11.745484 2.1397672071235366e-17 2.1020708402952523e-17 9.285976011161709e-19 23.042997 4.221840210623618e-18 4.131185018985201e-18 6.444221754064989e-19 0.34109023 6.5513577 7.504906339900869e-17 7.329433876931348e-17 1.5443880793287577e-18 48.594692 1.106027748951e-16 1.0928092222177462e-16 1.4964013632577832e-18 73.912506 2.5710959358072694e-16 2.461802169976991e-16 1.6533335823881433e-18 155.50981 + 26 3.231778506679122e-16 3.215726967630857e-16 2.6648693865814774e-18 121.27343 3.1924778492628656e-17 2.999046462393591e-17 1.8405701055414883e-18 17.345049 7.510285786120747e-17 6.780224478482187e-17 1.7769103727277057e-18 42.26598 8.322644095601701e-18 8.85226195580566e-18 1.241668496298282e-18 0.51718056 6.7027907 1.5678841778822867e-16 1.5688884290683858e-16 1.8804896069775027e-18 83.37638 2.6608799221349905e-16 2.6556053235498836e-16 1.8351058230267763e-18 144.99872 6.633374973371428e-16 6.722591656501161e-16 1.860696790688633e-18 356.4995 + 27 1.1781352146602502e-16 1.1568066603505909e-16 1.9325813895382948e-18 60.96174 1.3854795035992936e-17 1.3458544572302723e-17 1.331107237998098e-18 10.408474 2.843441559596412e-17 2.792247982822936e-17 1.198928550149139e-18 23.716522 8.149200554149742e-18 9.042394831111263e-18 1.1713002910848007e-18 0.72863233 6.9573965 7.231260258388283e-17 7.121131401404995e-17 1.461144641801931e-18 49.49038 1.4193221893146127e-16 1.4043960251936406e-16 1.4230384049489968e-18 99.73885 4.2431814382496466e-16 4.1890830692474527e-16 1.4121190002815738e-18 300.48328 + 28 2.436773764116529e-16 2.440814375972728e-16 1.2211953929473183e-18 199.54004 4.5369550582746754e-17 4.487978458658598e-17 7.494574090509646e-19 60.53653 9.162468445360598e-17 9.155384227242893e-17 7.882191448081719e-19 116.24265 1.0702321404034646e-17 1.0518265044208185e-17 7.063453945923944e-19 0.6369672 15.151683 2.260526084970116e-16 2.276268988106901e-16 9.159357420076349e-19 246.79964 4.2124873354796934e-16 4.264610732934911e-16 1.058101381417175e-18 398.11755 1.306304194046299e-15 1.2979939302038272e-15 1.0228585130195023e-18 1277.1113 diff --git a/tests_data/DEEP2_Ly2015/bin_emission_line_fit.tbl b/tests_data/DEEP2_Ly2015/bin_emission_line_fit.tbl new file mode 120000 index 00000000..13648501 --- /dev/null +++ b/tests_data/DEEP2_Ly2015/bin_emission_line_fit.tbl @@ -0,0 +1 @@ +DEEP2_Ly2015_fluxes.tbl \ No newline at end of file diff --git a/tests_data/DEEP2_Ly2015/bin_info.tbl b/tests_data/DEEP2_Ly2015/bin_info.tbl new file mode 100644 index 00000000..988fa6f1 --- /dev/null +++ b/tests_data/DEEP2_Ly2015/bin_info.tbl @@ -0,0 +1,30 @@ +bin_ID N_stack +------ ------- + 1 1 + 2 1 + 3 1 + 4 1 + 5 1 + 6 1 + 7 1 + 8 1 + 9 1 + 10 1 + 11 1 + 12 1 + 13 1 + 14 1 + 15 1 + 16 1 + 17 1 + 18 1 + 19 1 + 20 1 + 21 1 + 22 1 + 23 1 + 24 1 + 25 1 + 26 1 + 27 1 + 28 1 diff --git a/tests_data/DEEP2_Ly2015/bin_validation.revised.tbl b/tests_data/DEEP2_Ly2015/bin_validation.revised.tbl new file mode 120000 index 00000000..9563f1e8 --- /dev/null +++ b/tests_data/DEEP2_Ly2015/bin_validation.revised.tbl @@ -0,0 +1 @@ +bin_validation.tbl \ No newline at end of file diff --git a/tests_data/DEEP2_Ly2015/bin_validation.tbl b/tests_data/DEEP2_Ly2015/bin_validation.tbl new file mode 100644 index 00000000..6b80e712 --- /dev/null +++ b/tests_data/DEEP2_Ly2015/bin_validation.tbl @@ -0,0 +1,30 @@ +bin_ID N_stack Detection OIII_4363_Flux_Observed OIII_4363_S/N +------ ------- --------- ----------------------- ------------- + 1 1 1.0 6.936906146839537e-18 4.9357505 + 2 1 1.0 6.690768462851853e-18 5.914799 + 3 1 1.0 3.7042160815368825e-18 3.6640327 + 4 1 1.0 1.3092024823934616e-17 5.4533486 + 5 1 1.0 1.2753365398246719e-17 9.999132 + 6 1 1.0 3.9825209681568884e-18 5.0479355 + 7 1 1.0 5.754788289471245e-18 3.3903286 + 8 1 1.0 5.248943432691962e-18 3.9527802 + 9 1 1.0 3.415297994662249e-18 3.5532653 + 10 1 1.0 8.364974931074022e-18 6.43144 + 11 1 1.0 6.793400645597635e-18 7.7193575 + 12 1 1.0 1.0895289625862764e-17 13.213635 + 13 1 1.0 2.9376194276732592e-18 5.2345395 + 14 1 1.0 9.469657692776971e-18 9.32285 + 15 1 1.0 1.1962008793230175e-17 13.561061 + 16 1 1.0 6.774770798001975e-18 3.4026716 + 17 1 1.0 4.637125106677875e-18 4.2964764 + 18 1 1.0 4.291230911009648e-18 4.420166 + 19 1 1.0 7.41170466916978e-18 5.225789 + 20 1 1.0 7.734628766400586e-18 4.129208 + 21 1 1.0 6.620468272154165e-18 4.965434 + 22 1 1.0 6.24520023978129e-18 5.2504344 + 23 1 1.0 3.196077715577586e-18 3.2178385 + 24 1 1.0 9.603446777561852e-18 9.552306 + 25 1 1.0 4.131185018985201e-18 6.5513577 + 26 1 1.0 8.85226195580566e-18 6.7027907 + 27 1 1.0 9.042394831111263e-18 6.9573965 + 28 1 1.0 1.0518265044208185e-17 15.151683