Skip to content

Commit 27f8081

Browse files
Merge branch 'develop' into hp
2 parents 8e98be1 + b247952 commit 27f8081

7 files changed

Lines changed: 726 additions & 120 deletions

File tree

.github/workflows/ci-build.yml

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
os: [ubuntu-latest, macos-latest]
17-
python-version: [3.8]
17+
python-version: [3.10.12]
1818

1919
steps:
2020
- name: Checkout
@@ -29,29 +29,15 @@ jobs:
2929
env:
3030
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3131

32-
- name: Set up Conda with Python ${{ matrix.python-version }}
33-
uses: conda-incubator/setup-miniconda@v2
34-
with:
35-
auto-update-conda: true
36-
python-version: ${{ matrix.python-version }}
37-
auto-activate-base: false
38-
39-
- name: Check Conda
40-
shell: bash -l {0}
41-
run: |
42-
conda info
43-
conda list
44-
python --version
32+
- name: Install Poetry
33+
run: pip install poetry
4534

4635
- name: Install Dependencies
4736
shell: bash -l {0}
48-
run: |
49-
python --version
50-
python -m pip install --upgrade pip
51-
python -m pip install -r develop.txt
52-
python -m pip install -r docs/requirements.txt
53-
python -m pip install twine
54-
python -m pip install .
37+
run: poetry install
38+
39+
- name: Build Package
40+
run: poetry build
5541

5642
- name: Run Tests
5743
shell: bash -l {0}
@@ -66,12 +52,6 @@ jobs:
6652
name: unit-test-results-${{ matrix.os }}-${{ matrix.python-version }}
6753
path: pytest.xml
6854

69-
- name: Check Distribution
70-
shell: bash -l {0}
71-
run: |
72-
python setup.py sdist
73-
twine check dist/*
74-
7555
- name: Check API Documentation build
7656
shell: bash -l {0}
7757
run: |

cs_util/args.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import sys
1111
import os
12+
import shlex
1213

1314
from optparse import OptionParser
1415

@@ -103,6 +104,9 @@ def my_string_split(string, num=-1, verbose=False, stop=False, sep=None):
103104
the first in the list [space, underscore] that occurs in the string.
104105
(Thus, if both occur, use space.)
105106
107+
Handles quoted strings: entries containing spaces can be enclosed
108+
in double quotes, e.g., 'value1 "entry with spaces" value3'.
109+
106110
Parameters
107111
----------
108112
string : str
@@ -131,6 +135,19 @@ def my_string_split(string, num=-1, verbose=False, stop=False, sep=None):
131135
if string is None:
132136
return None
133137

138+
# Handle quoted strings with shlex
139+
if '"' in string or "'" in string:
140+
try:
141+
res = shlex.split(string)
142+
if num != -1 and num != len(res) and stop:
143+
raise ValueError(
144+
f"String has {len(res)} elements, required is {num}"
145+
)
146+
return res
147+
except ValueError:
148+
# Fall through to regular splitting if shlex fails
149+
pass
150+
134151
if sep is None:
135152
has_space = string.find(" ")
136153
has_underscore = string.find("_")
@@ -162,7 +179,7 @@ def my_string_split(string, num=-1, verbose=False, stop=False, sep=None):
162179

163180
if num != -1 and num != len(res) and stop:
164181
raise ValueError(
165-
f"String '{len(res)}' has length {num}, required is {num}"
182+
f"String has {len(res)} elements, required is {num}"
166183
)
167184

168185
return res

cs_util/cat.py

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,21 @@
1111
import os
1212
from datetime import datetime
1313

14+
from importlib.metadata import version
15+
import numpy as np
1416
import healpy as hp
1517

1618
from astropy.io import fits
1719
from astropy.io import ascii
1820
from astropy.table import Table
1921

2022

21-
def write_header_info_sp(primary_header, name="unknown", version="unknown"):
23+
def write_header_info_sp(
24+
primary_header,
25+
software_name="cs_util",
26+
software_version="unknown",
27+
author=None,
28+
):
2229
"""Write Header Info sp_validation.
2330
2431
Write information about software and run to FITS header
@@ -27,27 +34,37 @@ def write_header_info_sp(primary_header, name="unknown", version="unknown"):
2734
----------
2835
primary_header : dict
2936
FITS header information
30-
name : str
31-
software name, default is 'unknown'
32-
version : str
33-
version, default is 'unknown'
37+
software_name : str, optional
38+
software name; default is "cs_util"
39+
software_version : str, optional
40+
version; default is current cs_util version
41+
author : str, optional
42+
author name; if ``None`` (default), read from os.environ["USER"],
43+
or if not set in env, "unknown"
3444
3545
Returns
3646
-------
3747
dict
3848
updated FITS header information
3949
4050
"""
41-
if "USER" in os.environ:
42-
author = os.environ["USER"]
51+
if software_version is None:
52+
software_version = version("cs_util")
53+
54+
if author is None:
55+
if "USER" in os.environ:
56+
author = os.environ["USER"]
57+
else:
58+
author = "unknown"
4359
else:
4460
author = "unknown"
61+
4562
primary_header["AUTHOR"] = (author, "Who ran the software")
46-
primary_header["SOFTNAME"] = (name, "Name of the software")
47-
primary_header["SOFTVERS"] = (version, "Version of the software")
63+
primary_header["SOFTNAME"] = (software_name, "Software name")
64+
primary_header["SOFTVERS"] = (software_version, "software version")
4865
primary_header["DATE"] = (
4966
datetime.now().strftime("%Y-%m-%d_%H-%M-%S"),
50-
"When it was started",
67+
"Creation date",
5168
)
5269

5370
return primary_header
@@ -171,6 +188,39 @@ def write_fits_BinTable_file(
171188
hdu_list.writeto(output_path, overwrite=True)
172189

173190

191+
def read_fits_to_dict(file_path):
192+
"""Read Fits To Dict.
193+
194+
Read FITS file and return dictionary.
195+
196+
Parameters
197+
----------
198+
file_path : str
199+
input file path
200+
201+
Returns
202+
-------
203+
dict
204+
file content
205+
206+
Raises
207+
------
208+
IOError
209+
if input file is not found
210+
"""
211+
if not os.path.exists(file_path):
212+
raise IOError(f"Input file '{file_path}' not found")
213+
214+
hdu_list = fits.open(file_path)
215+
data_input = hdu_list[1].data
216+
col_names = hdu_list[1].data.dtype.names
217+
data = {}
218+
for col_name in col_names:
219+
data[col_name] = data_input[col_name]
220+
221+
return data
222+
223+
174224
def bin_edges2centers(bin_edges):
175225
"""Bin Edges To Centers.
176226
@@ -204,19 +254,36 @@ def read_dndz(file_path):
204254
205255
Returns
206256
-------
207-
list :
257+
np.array
208258
redshift bin centers
209-
list :
259+
np.array
210260
number densities
211-
list :
212-
redshift bin edges
261+
np.array
262+
redshift bin edges; one less than centers and density arrays
213263
214264
"""
215-
dat = ascii.read(file_path, format="commented_header")
265+
try:
266+
# Expecting header line "# z dn_dz"
267+
dat = ascii.read(file_path, format="commented_header")
268+
missing = [col for col in ("z", "dn_dz") if col not in dat.dtype.names]
269+
if missing:
270+
raise ValueError(
271+
f"Missing columns in dndz path {file_path}: {missing}"
272+
)
273+
except:
274+
# No header line
275+
dat = ascii.read(file_path)
276+
dat.rename_column("col1", "z")
277+
dat.rename_column("col2", "dn_dz")
278+
279+
# Remove last n(z) value which should be zero, to match bin centers
280+
tolerance = 1e-5
281+
if dat["dn_dz"][-1] / sum(dat["dn_dz"]) > tolerance:
282+
raise ValueError("dn_dz at last z-edge = {dat['dn_dz'][-1]}, no zero")
216283

217-
# Remove last n(z) value which is zero, to match bin centers
218284
nz = dat["dn_dz"][:-1]
219285
z_edges = dat["z"]
286+
220287
z_centers = bin_edges2centers(z_edges)
221288

222289
return z_centers, nz, z_edges

cs_util/cosmo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ def sigma_crit(z_lens, z_source, cos, d_lens=None, d_source=None):
7979

8080
a_lens = 1 / (1 + z_lens)
8181
a_source = 1 / (1 + z_source)
82-
if not d_lens:
82+
if d_lens is None:
8383
d_lens = cos.angular_diameter_distance(a_lens) * units.Mpc
84-
if not d_source:
84+
if d_source is None:
8585
d_source = cos.angular_diameter_distance(a_source) * units.Mpc
8686

8787
d_lens_source = cos.angular_diameter_distance(a_lens, a_source) * units.Mpc

0 commit comments

Comments
 (0)