Skip to content

Commit

Permalink
config.py modified for user-defined constant file use
Browse files Browse the repository at this point in the history
  • Loading branch information
abhi0395 committed Aug 1, 2024
1 parent fd45f70 commit 3ddb3d2
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 47 deletions.
6 changes: 4 additions & 2 deletions data/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ The input `fits file` must have the following HDU extensions:
- **FLUX**: Should ideally contain the residual spectra (usually the flux/continuum, i.e., the continuum normalized spectra).
- **WAVELENGTH**: Observed wavelength (in Angstroms).
- **ERROR**: Error on residuals.
- **TGTDETAILS**: Spectral details (such as Z_QSO, RA_QSO, DEC_QSO).
- **METADATA**: Spectral details (such as Z_QSO, RA_QSO, DEC_QSO).

Constant File (Optional)
------------------------

Before using your own constant file, please set an environment variable `QSO_CONSTANTS_FILE` in your `bashrc` or `zshrc` file and point it to the `qsoabsfind.constants` file. As the code loads the constants from new file dynamically, it is important to define this environment variable.

The user-defined **constant-file** must follow the same structure as the `qsoabsfind.constants` file, otherwise, the code will fail. If you want to use the default search parameters, you can run the tool without the `constant-file` option.

Running the Tool
Expand Down Expand Up @@ -57,6 +59,6 @@ The **output** `fits file` will have the `ABSORBER` HDU, containing arrays such
- **${metal}_EW_TOTAL**: Total EW of the lines in Angstroms.
- **${metal}_EW_TOTAL_ERROR**: Uncertainties in total EW of the lines in Angstroms.

Thanks,
Thanks,
Abhijeet Anand
Lawrence Berkeley National Lab
2 changes: 2 additions & 0 deletions docs/fileformat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The input `fits file` must have the following HDU extensions:
Constant File (Optional)
------------------------

Before using your own constant file, please set an environment variable `QSO_CONSTANTS_FILE` in your bashrc or zshrc file and point it to the qsoabsfind.constants file. As the code loads the constants from new file dynamically, it is important to define this environment variable.

The user-defined **constant-file** must follow the same structure as the `qsoabsfind.constants` file, otherwise, the code will fail. If you want to use the default search parameters, you can run the tool without the `constant-file` option.

Then run `qsoabsfind` with the required FITS file. If using a custom constant file, include it in the command:
Expand Down
5 changes: 4 additions & 1 deletion qsoabsfind/absfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
contiguous_pixel_remover, estimate_snr_for_lines, absorber_search_window
)
from .ew import measure_absorber_properties_double_gaussian
from .config import lines, speed_of_light, oscillator_parameters
from .config import load_constants
from .spec import QSOSpecRead
from numba import jit

constants = load_constants()
lines, oscillator_parameters, speed_of_light = constants.lines, constants.oscillator_parameters, constants.speed_of_light

@jit(nopython=True)
def find_valid_indices(our_z, residual_our_z, lam_search, conv_arr, sigma_cr, coeff_sigma, d_pix, beta, line1, line2):
"""
Expand Down
5 changes: 4 additions & 1 deletion qsoabsfind/absorberutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
"""

import numpy as np
from .config import speed_of_light, lines
from .config import load_constants
from .utils import elapsed
from numba import jit

constants = load_constants()
lines, speed_of_light = constants.lines, constants.speed_of_light

@jit(nopython=True)
def estimate_local_sigma_conv_array(conv_array, pm_pixel):
"""
Expand Down
42 changes: 24 additions & 18 deletions qsoabsfind/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,31 @@
3. Import constants from this module in other parts of the application to use the loaded constants.
"""

import importlib.util
import os
import importlib.util
import qsoabsfind.constants as default_constants

from .constants import *

def load_constants(constants_file):
"""Dynamically loads constants from a user-provided file.
Parameters:
constants_file (str): Path to the file containing user-defined constants.
def load_constants():
"""
spec = importlib.util.spec_from_file_location("user_constants", constants_file)
user_constants = importlib.util.module_from_spec(spec)
spec.loader.exec_module(user_constants)

# Update the globals dictionary with the user-defined constants
globals().update(user_constants.__dict__)
Load constants from the user-provided file if specified, otherwise use the default constants (qsoabsfind.constants).
If user provides a constant file, this function will read QSO_CONSTANTS_FILE environment
variable, initially set when user provides a constant file.
# Check if the environment variable for the constants file is set
constants_file = os.getenv('QSO_CONSTANTS_FILE')
if constants_file and os.path.isfile(constants_file):
load_constants(constants_file)
Returns:
module: The module containing the constants.
"""
constants_file = os.environ.get('QSO_CONSTANTS_FILE')

# Check if the environment variable for the constants file is set
if constants_file and os.path.isfile(constants_file):
try:
spec = importlib.util.spec_from_file_location("user_constants", constants_file)
user_constants = importlib.util.module_from_spec(spec)
spec.loader.exec_module(user_constants)
return user_constants
except Exception as e:
print(f"Error loading user constants: {e}. Falling back to default constants.")
return default_constants
else:
print("Using default constants.")
return default_constants
5 changes: 4 additions & 1 deletion qsoabsfind/ew.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

import numpy as np
from scipy.optimize import curve_fit
from .config import lines
from .utils import double_gaussian
from .absorberutils import redshift_estimate
from .config import load_constants

constants = load_constants()
lines = constants.lines

# Example usage within double_curve_fit
def double_curve_fit(index, fun_to_run, lam_fit_range, nmf_resi_fit, error_fit, bounds, init_cond, iter_n):
Expand Down
49 changes: 27 additions & 22 deletions qsoabsfind/parallel_convolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import re
import os
import pkg_resources

# Ensure config is imported first to set up the environment
import qsoabsfind.config as config
from .config import load_constants

def get_package_versions():
"""
Expand Down Expand Up @@ -158,7 +156,14 @@ def main():

# Set the environment variable for the constants file
if args.constant_file:
os.environ['QSO_CONSTANTS_FILE'] = args.constant_file
if not os.path.isabs(args.constant_file):
args.constant_file = os.path.abspath(os.path.join(os.getcwd(), args.constant_file))
os.environ['QSO_CONSTANTS_FILE'] = args.constant_file
print(f"INFO: Using user-provided constants from: {args.constant_file}")

print(f"INFO: QSO_CONSTANTS_FILE: {os.environ['QSO_CONSTANTS_FILE']}")
# set the new constants
constants = load_constants()

# Prepare headers
headers = {}
Expand All @@ -169,15 +174,15 @@ def main():
# Add search parameters and package versions to headers
headers.update({
'ABSORBER': {"value": args.absorber, "comment": 'Absorber name'},
'KERWIDTH': {"value": str(config.search_parameters[args.absorber]["ker_width_pixels"]), "comment": 'Kernel width in pixels'},
'COEFFSIG': {"value": config.search_parameters[args.absorber]["coeff_sigma"], "comment": 'Coefficient for sigma threshold'},
'MULTRE': {"value": config.search_parameters[args.absorber]["mult_resi"], "comment": 'Multiplicative factor for residuals'},
'D_PIX': {"value": config.search_parameters[args.absorber]["d_pix"], "comment": 'toloerance for line separation (in Ang)'},
'PM_PIXEL': {"value": config.search_parameters[args.absorber]["pm_pixel"], "comment": 'Pixel parameter for local noise estimation'},
'SN_LINE1': {"value": config.search_parameters[args.absorber]["sn_line1"], "comment": 'S/N threshold for first line'},
'SN_LINE2': {"value": config.search_parameters[args.absorber]["sn_line2"], "comment": 'S/N threshold for second line'},
'EWCOVAR': {"value": config.search_parameters[args.absorber]["use_covariance"], "comment": 'Use covariance for EW error calculation'},
'LOGWAVE': {"value": config.search_parameters[args.absorber]["logwave"], "comment": 'Use log wavelength scaling'}
'KERWIDTH': {"value": str(constants.search_parameters[args.absorber]["ker_width_pixels"]), "comment": 'Kernel width in pixels'},
'COEFFSIG': {"value": constants.search_parameters[args.absorber]["coeff_sigma"], "comment": 'Coefficient for sigma threshold'},
'MULTRE': {"value": constants.search_parameters[args.absorber]["mult_resi"], "comment": 'Multiplicative factor for residuals'},
'D_PIX': {"value": constants.search_parameters[args.absorber]["d_pix"], "comment": 'toloerance for line separation (in Ang)'},
'PM_PIXEL': {"value": constants.search_parameters[args.absorber]["pm_pixel"], "comment": 'Pixel parameter for local noise estimation'},
'SN_LINE1': {"value": constants.search_parameters[args.absorber]["sn_line1"], "comment": 'S/N threshold for first line'},
'SN_LINE2': {"value": constants.search_parameters[args.absorber]["sn_line2"], "comment": 'S/N threshold for second line'},
'EWCOVAR': {"value": constants.search_parameters[args.absorber]["use_covariance"], "comment": 'Use covariance for EW error calculation'},
'LOGWAVE': {"value": constants.search_parameters[args.absorber]["logwave"], "comment": 'Use log wavelength scaling'}
})

package_versions = get_package_versions()
Expand All @@ -195,15 +200,15 @@ def main():
# Run the convolution method in parallel
results = parallel_convolution_method_absorber_finder_QSO_spectra(
args.input_fits_file, spec_indices, absorber=args.absorber,
ker_width_pixels=config.search_parameters[args.absorber]["ker_width_pixels"],
coeff_sigma=config.search_parameters[args.absorber]["coeff_sigma"],
mult_resi=config.search_parameters[args.absorber]["mult_resi"],
d_pix=config.search_parameters[args.absorber]["d_pix"],
pm_pixel=config.search_parameters[args.absorber]["pm_pixel"],
sn_line1=config.search_parameters[args.absorber]["sn_line1"],
sn_line2=config.search_parameters[args.absorber]["sn_line2"],
use_covariance=config.search_parameters[args.absorber]["use_covariance"],
logwave=config.search_parameters[args.absorber]["logwave"], verbose=config.search_parameters[args.absorber]["verbose"], n_jobs=args.n_tasks * args.ncpus
ker_width_pixels=constants.search_parameters[args.absorber]["ker_width_pixels"],
coeff_sigma=constants.search_parameters[args.absorber]["coeff_sigma"],
mult_resi=constants.search_parameters[args.absorber]["mult_resi"],
d_pix=constants.search_parameters[args.absorber]["d_pix"],
pm_pixel=constants.search_parameters[args.absorber]["pm_pixel"],
sn_line1=constants.search_parameters[args.absorber]["sn_line1"],
sn_line2=constants.search_parameters[args.absorber]["sn_line2"],
use_covariance=constants.search_parameters[args.absorber]["use_covariance"],
logwave=constants.search_parameters[args.absorber]["logwave"], verbose=constants.search_parameters[args.absorber]["verbose"], n_jobs=args.n_tasks * args.ncpus
)

# Save the results to a FITS file
Expand Down
5 changes: 4 additions & 1 deletion qsoabsfind/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import time
#import logging
import numpy as np
from .config import lines, amplitude_dict, speed_of_light
from .config import load_constants
import matplotlib.pyplot as plt
import os

Expand All @@ -15,6 +15,9 @@
# Set the logging level for Matplotlib to WARNING to suppress DEBUG messages
#logging.getLogger('matplotlib').setLevel(logging.WARNING)

constants = load_constants()
lines, amplitude_dict, speed_of_light = constants.lines, constants.amplitude_dict, constants.speed_of_light

def elapsed(start, msg):
"""
Prints the elapsed time since `start`.
Expand Down
Binary file modified tests/__pycache__/test_constants.cpython-39.pyc
Binary file not shown.
5 changes: 4 additions & 1 deletion tests/test_constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import unittest
from qsoabsfind.config import lines, search_parameters, speed_of_light
from qsoabsfind.config import load_constants
constants = load_constants()

lines, search_parameters, speed_of_light = constants.lines, constants.search_parameters, constants.speed_of_light

class TestConstants(unittest.TestCase):
def test_line_data(self):
Expand Down

0 comments on commit 3ddb3d2

Please sign in to comment.