Skip to content

Commit e335876

Browse files
Replace pytables with h5py
When reading/writing calibration files
1 parent 6ad19fd commit e335876

3 files changed

Lines changed: 46 additions & 38 deletions

File tree

bilby/gw/detector/calibration.py

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -107,39 +107,42 @@ def read_calibration_file(
107107
Shape is (number_of_response_curves x len(frequency_array))
108108
109109
"""
110-
import tables
110+
import h5py
111111

112112
correction_type = _check_calibration_correction_type(correction_type=correction_type)
113113

114114
logger.info(f"Reading calibration draws from {filename}")
115-
calibration_file = tables.open_file(filename, 'r')
116-
calibration_amplitude = \
117-
calibration_file.root.deltaR.draws_amp_rel[starting_index:number_of_response_curves + starting_index]
118-
calibration_phase = \
119-
calibration_file.root.deltaR.draws_phase[starting_index:number_of_response_curves + starting_index]
120-
121-
calibration_frequencies = calibration_file.root.deltaR.freq[:]
122-
123-
calibration_file.close()
124-
125-
if len(calibration_amplitude.dtype) != 0: # handling if this is a calibration group hdf5 file
126-
calibration_amplitude = calibration_amplitude.view(np.float64).reshape(calibration_amplitude.shape + (-1,))
127-
calibration_phase = calibration_phase.view(np.float64).reshape(calibration_phase.shape + (-1,))
128-
calibration_frequencies = calibration_frequencies.view(np.float64)
129-
130-
# interpolate to the frequency array (where if outside the range of the calibration uncertainty its fixed to 1)
115+
with h5py.File(filename, 'r') as calibration_file:
116+
try:
117+
dr = calibration_file['deltaR']
118+
except KeyError:
119+
raise KeyError(f"File {filename} does not contain 'deltaR' group.")
120+
121+
# slice draws according to starting_index and number_of_response_curves
122+
calibration_amplitude = dr['draws_amp_rel'][starting_index: starting_index + number_of_response_curves]
123+
calibration_phase = dr['draws_phase'][starting_index: starting_index + number_of_response_curves]
124+
calibration_frequencies = dr['freq'][:]
125+
126+
# read parameter draws if present; stored under CalParams/table as a structured dataset
127+
parameter_draws = None
128+
if 'CalParams' in calibration_file and 'table' in calibration_file['CalParams']:
129+
table_ds = calibration_file['CalParams']['table']
130+
try:
131+
rec = np.array(table_ds)
132+
# convert structured array to DataFrame
133+
parameter_draws = pd.DataFrame.from_records(rec)
134+
except Exception:
135+
parameter_draws = None
136+
137+
# calibration_amplitude and calibration_phase should be arrays of shape (n_curves, n_freq)
138+
# combine into complex responses and interpolate to requested frequency array
131139
calibration_draws = calibration_amplitude * np.exp(1j * calibration_phase)
132140
calibration_draws = interp1d(
133141
calibration_frequencies, calibration_draws, kind='cubic',
134142
bounds_error=False, fill_value=1)(frequency_array)
135143
if correction_type == "data":
136144
calibration_draws = 1 / calibration_draws
137145

138-
try:
139-
parameter_draws = pd.read_hdf(filename, key="CalParams")
140-
except KeyError:
141-
parameter_draws = None
142-
143146
return calibration_draws, parameter_draws
144147

145148

@@ -170,27 +173,34 @@ def write_calibration_file(
170173
.. versionadded:: 1.4.0
171174
172175
"""
173-
import tables
176+
import h5py
174177

175178
correction_type = _check_calibration_correction_type(correction_type=correction_type)
176179

180+
# if the correction is specified as mapping data -> template, invert when writing
177181
if correction_type == "data":
178182
calibration_draws = 1 / calibration_draws
179183

180184
logger.info(f"Writing calibration draws to {filename}")
181-
calibration_file = tables.open_file(filename, 'w')
182-
deltaR_group = calibration_file.create_group(calibration_file.root, 'deltaR')
183-
184-
# Save output
185-
calibration_file.create_carray(deltaR_group, 'draws_amp_rel', obj=np.abs(calibration_draws))
186-
calibration_file.create_carray(deltaR_group, 'draws_phase', obj=np.angle(calibration_draws))
187-
calibration_file.create_carray(deltaR_group, 'freq', obj=frequency_array)
188-
189-
calibration_file.close()
190-
191-
# Save calibration parameter draws
192-
if calibration_parameter_draws is not None:
193-
calibration_parameter_draws.to_hdf(filename, key='CalParams', data_columns=True, format='table')
185+
# overwrite/create the file
186+
with h5py.File(filename, 'w') as calibration_file:
187+
deltaR_group = calibration_file.create_group('deltaR')
188+
189+
# Save output: amplitude and phase arrays
190+
amp = np.abs(calibration_draws)
191+
phase = np.angle(calibration_draws)
192+
deltaR_group.create_dataset('draws_amp_rel', data=amp, dtype=np.float64, compression='gzip')
193+
deltaR_group.create_dataset('draws_phase', data=phase, dtype=np.float64, compression='gzip')
194+
deltaR_group.create_dataset('freq', data=frequency_array, dtype=np.float64)
195+
196+
# Save calibration parameter draws (DataFrame) if provided. Store as a structured
197+
# dataset under CalParams/table so it can be read back into a DataFrame.
198+
if calibration_parameter_draws is not None:
199+
cp_group = calibration_file.create_group('CalParams')
200+
# convert DataFrame to a numpy recarray / structured array
201+
rec = calibration_parameter_draws.to_records(index=False)
202+
# create dataset
203+
cp_group.create_dataset('table', data=rec, compression='gzip')
194204

195205

196206
class Recalibrate(object):

containers/env-template.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ dependencies:
3131
- corner
3232
- healpy
3333
- cython
34-
- pytables
3534
- pytorch
3635
- cpuonly
3736
- python-lalsimulation

gw_requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
astropy>=5
22
lalsuite
33
gwpy
4-
tables
54
pyfftw
65
scikit-learn

0 commit comments

Comments
 (0)