Skip to content

Commit 93780b5

Browse files
author
sambit-giri
committed
fesc LyA constraints added
1 parent c0cc4d5 commit 93780b5

6 files changed

Lines changed: 102 additions & 7 deletions

File tree

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ scikit-image
88
tqdm
99
joblib
1010
pandas
11+
openpyxl
1112
pytest
1213
# torch==2.1.0
1314
# numba

src/tools21cm/compare_constraints.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
import numpy as np
22
import matplotlib.pyplot as plt
33
import os, sys
4+
from .read_files import get_package_resource_path
5+
6+
class EscapeFractionLymanAlpha:
7+
def __init__(self, verbose=True):
8+
self.verbose = verbose
9+
if self.verbose:
10+
print('--- Lyman-alpha Escape Fraction ---')
11+
self._load_constraints()
12+
13+
def _load_constraints(self):
14+
import pandas as pd
15+
16+
self.fesc_LymanAlpha_constraints = {}
17+
filename = get_package_resource_path('tools21cm', 'input_data/fesc_LyA_constraints.xlsx')
18+
19+
name = 'Napolitano+2024'
20+
df = pd.read_excel(filename, sheet_name=name, engine='openpyxl')
21+
self.fesc_LymanAlpha_constraints[name] = df
22+
23+
if self.verbose:
24+
print(f'Lyman-alpha escapse fraction references:\n{list(self.fesc_LymanAlpha_constraints.keys())}')
425

526
class ReionizationHistory:
6-
def __init__(self):
27+
def __init__(self, verbose=True):
28+
self.verbose = verbose
29+
if self.verbose:
30+
print('--- Reionization History ---')
731
self._load_constraints()
832
self._load_models()
933

@@ -175,6 +199,9 @@ def _load_constraints(self):
175199
{"redshift": 6.6, "redshift_error": [-0.0,0.0], "value": 0.21, "error": [-0.14,0.19], "type": "measurement", "method": method},
176200
]
177201

202+
if self.verbose:
203+
print(f'Observations:\n{list(self.neutral_fraction_constraints.keys())}')
204+
178205
def _load_models(self):
179206
self.neutral_fraction_models = {}
180207
method = 'pyC2Ray'
@@ -276,6 +303,9 @@ def _load_models(self):
276303
"method": method, "name": "Evolving IMF"},
277304
]
278305

306+
if self.verbose:
307+
print(f'Theory:\n{list(self.neutral_fraction_constraints.keys())}')
308+
279309
if __name__ == "__main__":
280310
import matplotlib.pyplot as plt
281311
from matplotlib.cm import ScalarMappable
10 KB
Binary file not shown.

src/tools21cm/radio_telescope_layout.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from . import cosmo as cm
66
from . import conv
77
from .const import KB_SI, c_light_cgs, c_light_SI, janskytowatt
8-
from importlib.resources import files
8+
from .read_files import get_package_resource_path
99
import astropy.units as u
1010
from astropy.coordinates import EarthLocation
1111

@@ -473,14 +473,14 @@ def get_SKA_Low_layout(subarray_type="AA4", unit='ecef', verbose=True):
473473
filename = 'input_data/skalow1_layout.txt'
474474

475475
# Load lat, lon, height from file
476-
lon, lat, height = np.loadtxt(str(files('tools21cm') / 'input_data/central_geographic_position.txt'))
476+
lon, lat, height = np.loadtxt(get_package_resource_path('tools21cm', 'input_data/central_geographic_position.txt'))
477477

478478
# EarthLocation of the array center
479479
core = EarthLocation(lat=lat * u.deg, lon=lon * u.deg, height=height * u.m)
480480
origin_ecef = np.array([core.x.value, core.y.value, core.z.value]) # in meters
481481

482482
# Load ENU antenna positions
483-
path_to_file = str(files('tools21cm') / filename)
483+
path_to_file = get_package_resource_path('tools21cm', filename)
484484
ant_enu = np.loadtxt(path_to_file) # shape (N_ant, 3)
485485

486486
if verbose:

src/tools21cm/read_files.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,68 @@ def recursive_save(h5obj, d):
303303
df.to_excel(filename, index=False)
304304

305305
else:
306-
raise ValueError(f"Unsupported format: {format}")
306+
raise ValueError(f"Unsupported format: {format}")
307+
308+
def get_package_resource_path(package_name, resource_path):
309+
"""
310+
Get the path to a resource file within a package, with automatic fallback
311+
for older Python versions.
312+
313+
Parameters
314+
----------
315+
package_name : str
316+
Name of the package (e.g., 'tools21cm')
317+
resource_path : str
318+
Path to the resource relative to the package root
319+
(e.g., 'input_data/central_geographic_position.txt')
320+
321+
Returns
322+
-------
323+
str or Path
324+
Path to the resource file that can be used with file reading functions
325+
326+
Examples
327+
--------
328+
>>> path = get_package_resource_path('tools21cm', 'input_data/central_geographic_position.txt')
329+
>>> data = np.loadtxt(path)
330+
"""
331+
332+
# Try importlib.resources first (Python 3.9+)
333+
try:
334+
from importlib.resources import files
335+
resource_file = files(package_name) / resource_path
336+
return str(resource_file)
337+
338+
except ImportError:
339+
# Fall back to importlib_resources (Python 3.6-3.8)
340+
try:
341+
from importlib_resources import files
342+
resource_file = files(package_name) / resource_path
343+
return str(resource_file)
344+
345+
except ImportError:
346+
# Fall back to pkg_resources (older versions)
347+
try:
348+
import pkg_resources
349+
return pkg_resources.resource_filename(package_name, resource_path)
350+
351+
except ImportError:
352+
# Last resort: try relative path (development mode)
353+
import os
354+
from pathlib import Path
355+
try:
356+
# Get the package's location
357+
package = __import__(package_name)
358+
package_dir = Path(package.__file__).parent
359+
resource_file = package_dir / resource_path
360+
361+
if resource_file.exists():
362+
return str(resource_file)
363+
else:
364+
raise FileNotFoundError(f"Resource not found: {resource_path}")
365+
366+
except Exception as e:
367+
raise ImportError(
368+
f"Could not locate resource '{resource_path}' in package '{package_name}'. "
369+
f"Please install 'importlib_resources' for Python < 3.9 or ensure the package is properly installed."
370+
) from e

src/tools21cm/segmentation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def __init__(self, tta=1, verbose=False):
108108

109109
def load_model(self):
110110
import tensorflow as tf
111-
import importlib.resources as pkg_resources
111+
from .read_files import get_package_resource_path
112112

113113
METRICS = {
114114
'balanced_cross_entropy': balanced_cross_entropy,
@@ -118,7 +118,7 @@ def load_model(self):
118118
'recall': recall
119119
}
120120

121-
MODEL_NAME = pkg_resources.resource_filename('tools21cm', 'input_data/segunet_03-11T12-02-05_128slice_ep35.h5')
121+
MODEL_NAME = get_package_resource_path('tools21cm', 'input_data/segunet_03-11T12-02-05_128slice_ep35.h5')
122122
self.MODEL_LOADED = tf.keras.models.load_model(MODEL_NAME, custom_objects=METRICS)
123123
print('Loaded model: %s' % MODEL_NAME)
124124

0 commit comments

Comments
 (0)