1111import os
1212from datetime import datetime
1313
14+ from importlib .metadata import version
15+ import numpy as np
1416import healpy as hp
1517
1618from astropy .io import fits
1719from astropy .io import ascii
1820from 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+
174224def 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
0 commit comments