@@ -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
196206class Recalibrate (object ):
0 commit comments