LALSimulation  5.4.0.1-fe68b98
LALSimNRSurRemnantUtils.c
Go to the documentation of this file.
1 /* Copyright (C) 2019 Vijay Varma
2  * Utils for evaluates NR surrogate remnant fits for the mass, spin and recoil
3  * kick of the final BH left behind in a BBH merger.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with with program; see the file COPYING. If not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301 USA
19  */
20 
21 /**
22  * \author Vijay Varma
23  *
24  * \file
25  *
26  * \brief Utils for NR surrogates for remnant BH mass, spin and recoil kick.
27  */
28 
29 #ifdef __GNUC__
30 #define UNUSED __attribute__ ((unused))
31 #else
32 #define UNUSED
33 #endif
34 
36 
37 #include <libgen.h>
38 
39 #include <gsl/gsl_bspline.h>
40 #include <gsl/gsl_blas.h>
41 #include <gsl/gsl_spline.h>
42 #include <gsl/gsl_complex_math.h>
43 
44 #include <lal/SeqFactories.h>
45 #include <lal/FileIO.h>
46 #include <lal/H5FileIO.h>
47 
48 #include <lal/XLALError.h>
49 #include <lal/LALConstants.h>
50 #include <lal/LALSimIMR.h>
51 
54 
55 //*************************************************************************/
56 //************************* function definitions **************************/
57 //*************************************************************************/
58 
59 //********************* Surrogate loading functions ************************/
60 // These should only be called once, when initializing the surrogate
61 
62 /**
63  * Loads H5 file for a NRSurRemnant model.
64  */
66  LALH5File **file, /**< Output: Returns the opened H5 file. */
67  const char* NRSurRemnant_DATAFILE /**< H5 file name to load. */
68 ) {
69 
70  char *path = XLAL_FILE_RESOLVE_PATH(NRSurRemnant_DATAFILE);
71  if (path==NULL) {
73  "Unable to find data file %s in $LAL_DATA_PATH\n",
74  NRSurRemnant_DATAFILE);
75  }
76 
77  char *dir = dirname(path);
78  const UINT4 size = strlen(dir) + strlen(NRSurRemnant_DATAFILE) + 2;
79  char *file_path = XLALMalloc(size);
80  snprintf(file_path, size, "%s/%s", dir, NRSurRemnant_DATAFILE);
81 
82  *file = XLALH5FileOpen(file_path, "r");
83  if (*file==NULL) {
85  "Unable to load data file %s in $LAL_DATA_PATH."
86  " File may be corrupted.\n", NRSurRemnant_DATAFILE);
87  }
88  XLALFree(path);
89  XLALFree(file_path);
90 }
91 
92 
93 /**
94  * Loads a single NRSurRemnant GPR fit, as described in the supplementary
95  * materials of arxiv:1809.09125.
96  */
98  ScalarFitData **fit_data, /**< Output: Fit data. *fit_data
99  should be NULL. Space will be allocated. */
100  LALH5File *file, /**< Opened H5 file. */
101  const char *grp_name /**< H5 group name. */
102 ) {
103 
104  if (fit_data == NULL || *fit_data != NULL) {
105  XLAL_ERROR(XLAL_EFAULT, "*fit_data should be NULL");
106  }
107  if (file == NULL) {
108  XLAL_ERROR(XLAL_EFAULT, "file should not be NULL");
109  }
110 
111  // Open h5 group
112  LALH5File *sub;
113  sub = XLALH5GroupOpen(file, grp_name);
114  *fit_data = XLALMalloc(sizeof(ScalarFitData));
115 
116  // Load fit data
117  GPRHyperParams *hyperparams = XLALMalloc(sizeof(GPRHyperParams));
118 
119  //// Load scalars needed for fit
120 
121  // constant_value = \sigma_k^2 in Eq. S3 of arxiv:1809.09125
122  int ret = ReadHDF5DoubleDataset(&(hyperparams->constant_value),
123  sub, "constant_value");
124  if (ret != XLAL_SUCCESS) {
125  XLAL_ERROR(XLAL_EFUNC, "Failed to load constant_value.");
126  }
127 
128  // Mean value before doing GPR fit, usually zero. We already remove the
129  // mean and store it in data_mean.
130  ret = ReadHDF5DoubleDataset(&(hyperparams->y_train_mean),
131  sub, "y_train_mean");
132  if (ret != XLAL_SUCCESS) {
133  XLAL_ERROR(XLAL_EFUNC, "Failed to load y_train_mean.");
134  }
135 
136  // Mean of fit data.
137  ret = ReadHDF5DoubleDataset(&((*fit_data)->data_mean),
138  sub, "data_mean");
139  if (ret != XLAL_SUCCESS) {
140  XLAL_ERROR(XLAL_EFUNC, "Failed to load data_mean.");
141  }
142 
143  // Standard deviation of fit data.
144  ret = ReadHDF5DoubleDataset(&((*fit_data)->data_std),
145  sub, "data_std");
146  if (ret != XLAL_SUCCESS) {
147  XLAL_ERROR(XLAL_EFUNC, "Failed to load data_std.");
148  }
149 
150  // Intercept of linear fit.
151  ret = ReadHDF5DoubleDataset(&((*fit_data)->lin_intercept),
152  sub, "lin_intercept");
153  if (ret != XLAL_SUCCESS) {
154  XLAL_ERROR(XLAL_EFUNC, "Failed to load lin_intercept.");
155  }
156 
157 
158  //// Load arrays needed for fit
159 
160  // Length scale parameters in the kernel.
161  // Array of size=dom, where dim=dimensions of the model.
162  hyperparams->length_scale = NULL;
163  ret = ReadHDF5RealVectorDataset(sub, "length_scale",
164  &(hyperparams->length_scale));
165  if (ret != XLAL_SUCCESS) {
166  XLAL_ERROR(XLAL_EFUNC, "Failed to load length_scale.");
167  }
168 
169  // alpha = \f$ K_{x x}^{-1} {\bf f}\f$, which is used in the mean value
170  // in Eq. S2 of arxiv:1809.09125. This can be precomputed as it does not
171  // depend on the x_{*} values.
172  // Array of size=N, where N=size of training dataset.
173  hyperparams->alpha = NULL;
174  ret = ReadHDF5RealVectorDataset(sub, "alpha",
175  &(hyperparams->alpha));
176  if (ret != XLAL_SUCCESS) {
177  XLAL_ERROR(XLAL_EFUNC, "Failed to load alpha.");
178  }
179 
180  // Coefs of of linear fit.
181  (*fit_data)->lin_coef = NULL;
182  ret = ReadHDF5RealVectorDataset(sub, "lin_coef", &((*fit_data)->lin_coef));
183  if (ret != XLAL_SUCCESS) {
184  XLAL_ERROR(XLAL_EFUNC, "Failed to load lin_coef.");
185  }
186 
187  (*fit_data)->hyperparams = hyperparams;
188 
189 
190  XLALH5FileClose(sub);
191  return ret;
192 }
193 
194 
195 /**
196  * Loads a vector of NRSurRemnant GPR fits
197  */
199  VectorFitData **vector_data, /**< Output: Vector of fit data. *vector_data
200  should be NULL. Space will be allocated. */
201  UINT4 vec_dim, /**< Length of the vector */
202  LALH5File *file, /**< Opened H5 file. */
203  const char *grp_name /**< H5 group name. */
204 ) {
205 
206  if (vector_data == NULL || *vector_data != NULL) {
207  XLAL_ERROR(XLAL_EFAULT, "*vector_data should be NULL");
208  }
209 
210  *vector_data = XLALMalloc(sizeof(VectorFitData));
211  (*vector_data)->fit_data = XLALMalloc( vec_dim * sizeof(ScalarFitData *) );
212 
213  const size_t str_size = 20;
214  char *sub_grp_name = XLALMalloc(str_size);
215  UNUSED size_t nwritten;
216 
217  // For each component load a Scalar fit
218  int ret = XLAL_SUCCESS;
219  for (UINT4 i=0; i<vec_dim; i++){
220 
221  nwritten = snprintf(sub_grp_name, str_size, "%s/comp_%u", grp_name, i);
222  XLAL_CHECK_ABORT(nwritten < str_size);
223 
224  ScalarFitData *fit_data = NULL;
225  ret = NRSurRemnant_LoadScalarFit(&fit_data, file, sub_grp_name);
226  (*vector_data)->fit_data[i] = fit_data;
227  }
228  (*vector_data)->vec_dim = vec_dim;
229 
230  return ret;
231 }
232 
233 /**
234  * Initializes fit data for a precessing NRSurRemnant.
235  *
236  * The data includes a ScalarFitData for the final mass, and a VectorFitData
237  * for the final spin and kick 3-vectors.
238  */
240  PrecessingRemnantFitData *sur_data, /**< Output: Loaded surrogate data. */
241  LALH5File *file /**< Opened H5 file. */
242 ) {
243 
244  if (sur_data == NULL) {
245  XLAL_ERROR(XLAL_EFAULT, "sur_data should not be NULL");
246  }
247  if (file == NULL) {
248  XLAL_ERROR(XLAL_EFAULT, "file should not be NULL");
249  }
250 
251  if (sur_data->setup) {
253  "Model was already initialized. Exiting.");
254  }
255 
256  // x_train contains the training parameters and are common for all fits
257  gsl_matrix *x_train = NULL;
258  int ret = ReadHDF5RealMatrixDataset(file, "GPR_X_train", &x_train);
259  if (ret != XLAL_SUCCESS) {
260  XLAL_ERROR(XLAL_EFUNC, "Failed to load GPR_X_train.");
261  }
262  sur_data->x_train = x_train;
263 
264  // dimension of the surrogate
265  sur_data->params_dim = x_train->size2;
266 
267  // final mass
268  sur_data->mf_data = NULL;
269  ret = NRSurRemnant_LoadScalarFit(&(sur_data->mf_data), file, "mf");
270 
271  // final spin vector
272  sur_data->chif_data = NULL;
273  NRSurRemnant_LoadVectorFit(&(sur_data->chif_data), 3, file, "chif");
274 
275  // recoil kick vector
276  sur_data->vf_data = NULL;
277  NRSurRemnant_LoadVectorFit(&(sur_data->vf_data), 3, file, "vf");
278 
279  if (ret == XLAL_SUCCESS){
280  sur_data->setup = 1;
281  }
282 
283  return ret;
284 }
285 
286 
287 /**
288  * Initializes fit data for an aligned-spin NRSurRemnant.
289  *
290  * The data includes a ScalarFitData for the final mass, z-component of the
291  * final spin, and x and y components of the recoil kick. The other components
292  * of the spin and kick are zero due to the symmetries of aligned-spin systems
293  * and are not modelled by the surrogate.
294  */
296  AlignedSpinRemnantFitData *sur_data, /**< Output: Loaded surrogate data. */
297  LALH5File *file /**< Opened H5 file. */
298 ) {
299 
300  if (sur_data == NULL) {
301  XLAL_ERROR(XLAL_EFAULT, "sur_data should not be NULL");
302  }
303  if (file == NULL) {
304  XLAL_ERROR(XLAL_EFAULT, "file should not be NULL");
305  }
306 
307  if (sur_data->setup) {
309  "Model was already initialized. Exiting.");
310  }
311 
312  // x_train contains the training parameters and are common for all fits
313  gsl_matrix *x_train = NULL;
314  int ret = ReadHDF5RealMatrixDataset(file, "GPR_X_train", &x_train);
315  if (ret != XLAL_SUCCESS) {
316  XLAL_ERROR(XLAL_EFUNC, "Failed to load GPR_X_train.");
317  }
318  sur_data->x_train = x_train;
319 
320  // dimension of the surrogate
321  sur_data->params_dim = x_train->size2;
322 
323  // final mass
324  sur_data->mf_data = NULL;
325  ret = NRSurRemnant_LoadScalarFit(&(sur_data->mf_data), file, "mf");
326 
327  // z-component of final spin (other components are zero)
328  sur_data->chifz_data = NULL;
329  ret = NRSurRemnant_LoadScalarFit(&(sur_data->chifz_data), file, "chifz");
330 
331  // x-component of recoil kick
332  sur_data->vfx_data = NULL;
333  ret = NRSurRemnant_LoadScalarFit(&(sur_data->vfx_data), file, "vfx");
334 
335  // y-component of recoil kick, z-component is zero
336  sur_data->vfy_data = NULL;
337  ret = NRSurRemnant_LoadScalarFit(&(sur_data->vfy_data), file, "vfy");
338 
339  if (ret == XLAL_SUCCESS){
340  sur_data->setup = 1;
341  }
342 
343  return ret;
344 }
struct tagLALH5File LALH5File
Auxiliary functions for SEOBNRv1/v2 reduced order modeling codes in LALSimIMRSEOBNRv2ROMDoubleSpin....
int ReadHDF5DoubleDataset(REAL8 *param, LALH5File *sub, const char *name)
Reads a REAL8 value from a H5 file/group.
int NRSurRemnant_LoadScalarFit(ScalarFitData **fit_data, LALH5File *file, const char *grp_name)
Loads a single NRSurRemnant GPR fit, as described in the supplementary materials of arxiv:1809....
void NRSurRemnant_LoadH5File(LALH5File **file, const char *NRSurRemnant_DATAFILE)
Loads H5 file for a NRSurRemnant model.
int NRSurRemnant_LoadVectorFit(VectorFitData **vector_data, UINT4 vec_dim, LALH5File *file, const char *grp_name)
Loads a vector of NRSurRemnant GPR fits.
int AlignedSpinNRSurRemnant_Init(AlignedSpinRemnantFitData *sur_data, LALH5File *file)
Initializes fit data for an aligned-spin NRSurRemnant.
int PrecessingNRSurRemnant_Init(PrecessingRemnantFitData *sur_data, LALH5File *file)
Initializes fit data for a precessing NRSurRemnant.
Utils for NR surrogates for remnant BH mass, spin and recoil kick.
#define ScalarFitData
double i
Definition: bh_ringdown.c:118
#define XLAL_FILE_RESOLVE_PATH(fname)
void XLALH5FileClose(LALH5File UNUSED *file)
LALH5File * XLALH5GroupOpen(LALH5File UNUSED *file, const char UNUSED *name)
LALH5File * XLALH5FileOpen(const char UNUSED *path, const char UNUSED *mode)
uint32_t UINT4
void * XLALMalloc(size_t n)
void XLALFree(void *p)
#define XLAL_ERROR_VOID(...)
#define XLAL_ERROR(...)
#define XLAL_CHECK_ABORT(assertion)
XLAL_SUCCESS
XLAL_EFAULT
XLAL_ENOENT
XLAL_EFUNC
XLAL_EIO
XLAL_FAILURE
path
NRSurRemnant GPR fit data for the mass, spin, and recoil kick for aligned-spin BBHs.
ScalarFitData * mf_data
Fit data for final mass.
UINT4 params_dim
Dimensions of the model.
gsl_matrix * x_train
Training set parameters, needed for GPR fits.
ScalarFitData * vfy_data
Fit data for final mass.
ScalarFitData * vfx_data
Fit data for final mass.
ScalarFitData * chifz_data
Fit data for final mass.
UINT4 setup
Indicates if NRSurRemnant has been initialized.
Data used in a single GPR fit.
REAL8 constant_value
in kernel.
gsl_vector * alpha
Precomputed .
gsl_vector * length_scale
in kernel.
REAL8 y_train_mean
Mean value before GPR fit, usually zero.
NRSurRemnant GPR fit data for the mass, spin, and recoil kick for generically precessing BBHs.
VectorFitData * vf_data
Fit data for recoil kick.
UINT4 setup
Indicates if NRSurRemnant has been initialized.
ScalarFitData * mf_data
Fit data for final mass.
UINT4 params_dim
Dimensions of the model.
VectorFitData * chif_data
Fit data for final spin.
gsl_matrix * x_train
Training set parameters, needed for GPR fits.
Data used in a single vector fit NOTE: basisFunctionOrders, coefs, componentIndices,...