Skip to content

Commit

Permalink
config and datamodel added
Browse files Browse the repository at this point in the history
  • Loading branch information
abhi0395 committed Jul 29, 2024
1 parent 47bdf68 commit e5aa8c4
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 15 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ python -m unittest discover -s tests

```

Instructions
-------------

Before you run, please read the `datamodel.md` file. The instructions about the input and output file are provided there.

Running example:
----------------

Expand Down
2 changes: 1 addition & 1 deletion qsoabsfind/absfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
contiguous_pixel_remover, check_error_on_residual, redshift_estimate, absorber_search_window
)
from .ew import measure_absorber_properties_double_gaussian
from .constants import lines, speed_of_light, oscillator_parameters
from .config import lines, speed_of_light, oscillator_parameters
from .spec import QSOSpecRead

def find_valid_indices(our_z, residual_our_z, lam_search, conv_arr, sigma_cr, coeff_sigma, d_pix, beta, line1, line2):
Expand Down
2 changes: 1 addition & 1 deletion qsoabsfind/absorberutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

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

Expand Down
40 changes: 40 additions & 0 deletions qsoabsfind/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# config.py

"""
This module handles dynamic loading of constants for the QSO absorber finder.
It first loads the default constants from the constants module and then optionally
overwrites them with user-provided constants from a specified file.
If an environment variable 'QSO_CONSTANTS_FILE' is set and points to a valid file, the constants
from that file will be loaded and used instead of the default ones.
Usage:
1. Ensure the default constants are defined in the constants module.
2. Optionally provide a custom constants file path in the environment variable 'QSO_CONSTANTS_FILE'.
3. Import constants from this module in other parts of the application to use the loaded constants.
"""

import importlib.util
import os

# 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.
"""
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__)

# 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)
40 changes: 40 additions & 0 deletions qsoabsfind/datamodel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
qsoabsfind
============

Instructions
-------------

Please read/perform following details.

`qsoabsfind --help`

Please go through all the functions and their instructions in case you have any doubt.

The **input** `fits file` must have a specific structure with following hdu extensions.

- `FLUX` Should contain ideally the residual spectra (usually the flux/continuum, i.e. the continuum normalized spectra)
- `WAVELENGTH` observed wavelength (in Ang)
- `ERROR` error on residuals
- `TGTDETALS` spectral details (like Z_QSO, RA_QSO, DEC_QSO...)

The user-defined **constant-file** must follow the same structure as the `qsoabsfind.constants`, otherwise the code will fail. In case, users want to use the default search parameters, they can tun without `constant-file` option.

The **output** `fits file` will have the hdu `ABSORBER`, that will arrays such as

- `INDEX_SPEC` index of quasar (can be used to read the RA, DEC ans Z of QSOs)
- `Z_ABS`: redshift of absorber
- `${METAL}_${line}_EW`: Rest-frame EWs of absorber lines (like MgII 2796, 2803 or CIV 1548, 1550) (in Ang)
- `${METAL}_${line}_EW_ERROR`: uncertainities in rest-frame EWs of absorber lines (like MgII 2796, 2803 or CIV 1548, 1550) (in Ang)
- `Z_ABS_ERR`: measured error in redshift of absorber
- `GAUSS_FIT`: rest-frame fitting parameters of double gaussian to the absorber doublet (the width can be used to measure the velocity dispersion)
- `GAUSS_FIT_STD`: uncertainities in rest-frame fitting parameters of double gaussian to the absorber doublet (the width can be used to measure the velocity dispersion)
- `SN_${METAL}_${line}`: S/N of the lines
- `${metal}_EW_TOTAL`: Total EW of the lines (in Ang)
- `${metal}_EW_TOTAL_ERROR`: uncertainities in total EW of the lines (in Ang)


Thanks,
Abhijeet Anand
Lawrence Berkeley National Lab

If you have any questions/suggestions, please feel free to write to [email protected]
2 changes: 1 addition & 1 deletion qsoabsfind/ew.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
from scipy.optimize import curve_fit
from .constants import lines
from .config import lines
from .utils import double_gaussian

# Example usage within double_curve_fit
Expand Down
30 changes: 20 additions & 10 deletions qsoabsfind/parallel_convolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
from .absfinder import convolution_method_absorber_finder_in_QSO_spectra
from .io import save_results_to_fits
import re
from .constants import search_parameters

def run_convolution_method_absorber_finder_QSO_spectra(fits_file, spec_index, absorber, ker_width_pix, coeff_sigma, mult_resi, d_pix, pm_pixel, sn_line1, sn_line2, use_covariance):
return convolution_method_absorber_finder_in_QSO_spectra(fits_file, spec_index, absorber, ker_width_pix, coeff_sigma, mult_resi, d_pix, pm_pixel, sn_line1, sn_line2, use_covariance)
from importlib import import_module

# Ensure config is imported first to set up the environment
import config

def run_convolution_method_absorber_finder_QSO_spectra(params):
return convolution_method_absorber_finder_in_QSO_spectra(*params)


def parse_qso_sequence(qso_sequence):
Expand Down Expand Up @@ -107,12 +111,18 @@ def main():
parser.add_argument('--input-fits-file', type=str, required=True, help='Path to the input FITS file.')
parser.add_argument('--n-qso', required=True, help="Number of QSO spectra to process, or a bash-like sequence (e.g., '1-1000', '1-1000:10').")
parser.add_argument('--absorber', type=str, required=True, help='Absorber name for searching doublets (MgII, CIV).')
parser.add_argument('--constant-file', type=str, help='Path to the constants .py file, please follow the exact same strcuture as qsoabsfind.constants, i.e the default parameter that the code uses')
parser.add_argument('--output', type=str, required=True, help='Path to the output FITS file.')
parser.add_argument('--headers', type=str, nargs='+', help='Headers for the output FITS file in the format NAME=VALUE.')
parser.add_argument('--n-tasks', type=int, required=True, help='Number of tasks.')
parser.add_argument('--ncpus', type=int, required=True, help='Number of CPUs per task.')

args = parser.parse_args()

# Set the environment variable for the constants file
if args.constant_file:
os.environ['QSO_CONSTANTS_FILE'] = args.constant_file

# Prepare headers
headers = {}
if args.headers:
Expand All @@ -129,13 +139,13 @@ 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_pix=search_parameters[args.absorber]["ker_width_pixels"],
coeff_sigma=search_parameters[args.absorber]["coeff_sigma"],
mult_resi=search_parameters[args.absorber]["mult_resi"],
d_pix=search_parameters[args.absorber]["d_pix"],
pm_pixel=search_parameters[args.absorber]["pm_pixel"],
sn_line1=search_parameters[args.absorber]["sn1_thresh"],
sn_line2=search_parameters[args.absorber]["sn2_thresh"],
ker_width_pix=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]["sn1_thresh"],
sn_line2=config.search_parameters[args.absorber]["sn2_thresh"],
use_covariance=False, n_jobs=args.n_tasks * args.ncpus
)

Expand Down
2 changes: 1 addition & 1 deletion qsoabsfind/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import time
import numpy as np
from .constants import lines, amplitude_dict
from .config import lines, amplitude_dict

def elapsed(start, msg):
"""
Expand Down
2 changes: 1 addition & 1 deletion tests/test_constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import unittest
from qsoabsfind.constants import lines, search_parameters, speed_of_light
from qsoabsfind.config import lines, search_parameters, speed_of_light

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

0 comments on commit e5aa8c4

Please sign in to comment.