Skip to content

Commit c06505d

Browse files
committed
cleaning
1 parent b9a31c4 commit c06505d

2 files changed

Lines changed: 65 additions & 47 deletions

File tree

validphys2/src/validphys/config.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import numbers
99
import pathlib
1010

11+
import numpy as np
1112
import pandas as pd
1213

1314
from nnpdf_data import legacy_to_new_map
@@ -848,21 +849,28 @@ def produce_dataset_inputs_sampling_covmat(
848849
else:
849850
return covmats.dataset_inputs_exp_covmat
850851

851-
def produce_loaded_fit_covmat(self, output_path, data_input):
852+
def produce_loaded_fit_covmat(self, output_path, data_input, diagonal_basis=True):
852853
"""
853854
Loads the theory covmat from the correct file according to how it
854855
was generated by vp-setupfit.
855856
"""
856857

857858
generic_path = "datacuts_theory_theorycovmatconfig_fitting_covmat_table.csv"
858859
fit_covmat_path = output_path / "tables" / generic_path
859-
fit_covmat = pd.read_csv(
860-
fit_covmat_path, index_col=[0, 1, 2], header=[0, 1, 2], sep="\t|,", engine="python"
861-
).fillna(0)
862-
# change ordering according to exp_covmat (so according to runcard order)
863-
tmp = fit_covmat.droplevel(0, axis=0).droplevel(0, axis=1)
864-
bb = [str(i) for i in data_input]
865-
return tmp.reindex(index=bb, columns=bb, level=0).values
860+
if not diagonal_basis:
861+
fit_covmat = pd.read_csv(
862+
fit_covmat_path, index_col=[0, 1, 2], header=[0, 1, 2], sep="\t|,", engine="python"
863+
).fillna(0)
864+
# change ordering according to exp_covmat (so according to runcard order)
865+
tmp = fit_covmat.droplevel(0, axis=0).droplevel(0, axis=1)
866+
bb = [str(i) for i in data_input]
867+
return tmp.reindex(index=bb, columns=bb, level=0).values
868+
else:
869+
eigensystem = pd.read_csv(
870+
fit_covmat_path, index_col=[0], header=[0], sep="\t|,", engine="python"
871+
)
872+
873+
return np.diag(eigensystem["eig_val"].values)
866874

867875
def produce_loaded_theory_covmat(
868876
self,

validphys2/src/validphys/n3fit_data.py

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -319,29 +319,62 @@ def _hashed_dataset_inputs_fitting_covmat(loaded_fit_covmat) -> Hashrray:
319319

320320

321321
@functools.lru_cache
322-
def _inv_covmat_prepared(_hashed_dataset_inputs_fitting_covmat):
322+
def _inv_covmat_prepared(_hashed_dataset_inputs_fitting_covmat, output_path, diagonal_basis=True):
323323
"""Returns the inverse covmats for training, validation and total when diagonal_basis = False"""
324324
log.info(
325325
f"_inv_covmat_prepared called with covmat hash={hash(_hashed_dataset_inputs_fitting_covmat)}"
326326
)
327327
covmat = _hashed_dataset_inputs_fitting_covmat.array
328+
diag_rot = None
329+
eig_vals = None
328330

329-
diag_inv_sqrt_total = 1 / np.sqrt(np.diag(covmat))
330-
cormat_total = np.einsum("i, ij, j -> ij", diag_inv_sqrt_total, covmat, diag_inv_sqrt_total)
331-
inv_total = (
332-
np.diag(diag_inv_sqrt_total) @ np.linalg.inv(cormat_total) @ np.diag(diag_inv_sqrt_total)
333-
)
331+
if diagonal_basis:
332+
diagonal_basis_saved = "datacuts_theory_theorycovmatconfig_fitting_covmat_table.csv"
333+
path_diagonal_basis = output_path / "tables" / diagonal_basis_saved
334+
eigensystem = pd.read_csv(
335+
path_diagonal_basis, index_col=[0], header=[0], sep="\t|,", engine="python"
336+
)
337+
diag_rot = eigensystem.iloc[:, 1:].values
338+
eig_vals = eigensystem["eig_val"].values
339+
inv_total = np.diag(1 / eig_vals)
340+
341+
else:
342+
diag_inv_sqrt_total = 1 / np.sqrt(np.diag(covmat))
343+
cormat_total = np.einsum("i, ij, j -> ij", diag_inv_sqrt_total, covmat, diag_inv_sqrt_total)
344+
inv_total = (
345+
np.diag(diag_inv_sqrt_total)
346+
@ np.linalg.inv(cormat_total)
347+
@ np.diag(diag_inv_sqrt_total)
348+
)
334349

335-
return inv_total
350+
return covmat, inv_total, diag_rot, eig_vals
336351

337352

338-
def _covmat_prepared(dataset_inputs_fitting_covmat, nnfit_theory_covmat, diagonal_basis=True):
339-
"""Returns the covmats for training, validation and total
340-
attending to the right masks and whether it is diagonal or not.
341-
s
342-
Since the masks and number of datapoints need to be treated for 1-point datasets
343-
it also returns the right ndata and masks for training and validation:
353+
def _fiting_covmat(dataset_inputs_fitting_covmat, nnfit_theory_covmat, diagonal_basis=True):
354+
"""Prepare the fitting covariance matrix by optionally adding theory contributions
355+
and transforming to diagonal basis.
344356
357+
Parameters
358+
----------
359+
dataset_inputs_fitting_covmat : np.ndarray
360+
The experimental covariance matrix from the datasets.
361+
nnfit_theory_covmat : np.ndarray or None
362+
The theory covariance matrix to add to the experimental covmat.
363+
If None, only the experimental covmat is used.
364+
diagonal_basis : bool, optional
365+
If True, transform the covariance matrix to diagonal basis by extracting
366+
eigenvalues and eigenvectors of the correlation matrix. Default is True.
367+
368+
Returns
369+
-------
370+
covmat : np.ndarray
371+
The prepared covariance matrix (sum of experimental and theory covmats).
372+
diagonal_rotation : np.ndarray or None
373+
The rotation matrix (transposed eigenvectors) to transform data to diagonal basis.
374+
Only returned if diagonal_basis=True, otherwise None.
375+
eig_vals : np.ndarray or None
376+
The eigenvalues of the correlation matrix in diagonal basis.
377+
Only returned if diagonal_basis=True, otherwise None.
345378
"""
346379

347380
# TODO: JtH, note to self: inv_covmat_prepared can no longer be called during n3fit because nnfit_theory_covmat is in a different namespace
@@ -365,10 +398,6 @@ def _covmat_prepared(dataset_inputs_fitting_covmat, nnfit_theory_covmat, diagona
365398
uT = np.einsum("i, ik -> ik", diag_inv_sqrt, uT)
366399
diagonal_rotation = uT.T
367400

368-
ndata = len(eig_vals)
369-
370-
inv_total = np.diag(1 / eig_vals)
371-
372401
return covmat, diagonal_rotation, eig_vals
373402

374403

@@ -432,26 +461,7 @@ def fitting_data_dict(
432461
fittable_datasets = fittable_datasets_masked
433462

434463
# load covmat stored at the time of vp-setupfit
435-
if diagonal_basis:
436-
diagonal_basis_saved = "datacuts_theory_theorycovmatconfig_fitting_covmat_table.csv"
437-
path_diagonal_basis = output_path / "tables" / diagonal_basis_saved
438-
eigensystem = pd.read_csv(
439-
path_diagonal_basis, index_col=[0], header=[0], sep="\t|,", engine="python"
440-
)
441-
diag_rot = eigensystem.iloc[:, 1:].values
442-
eig_vals = eigensystem["eig_val"].values
443-
inv_true = np.diag(1 / eig_vals)
444-
covmat = np.diag(eig_vals)
445-
else:
446-
covmat_saved = "datacuts_theory_theorycovmatconfig_fitting_covmat_table.csv"
447-
path_covmat = output_path / "tables" / covmat_saved
448-
# TODO: check if it is save to convert to numpy already at this stage, is the indexing consistent?
449-
covmat = pd.read_csv(
450-
path_covmat, index_col=[0, 1, 2], header=[0, 1, 2], sep="\t|,", engine="python"
451-
).values
452-
diag_rot = None
453-
eig_vals = None
454-
inv_true = _inv_covmat_prepared
464+
covmat, inv_true, diag_rot, eig_vals = _inv_covmat_prepared
455465

456466
# get the masks - different for each replica so fine to call here
457467
tr_mask, vl_mask = masks.tr_masks[0], masks.vl_masks[0]
@@ -579,12 +589,12 @@ def fitting_data_dict(
579589

580590

581591
@table
582-
def fitting_covmat_table(output_path, _covmat_prepared, diagonal_basis=True):
592+
def fitting_covmat_table(output_path, _fiting_covmat, diagonal_basis=True):
583593
"""
584594
Stores the fitting covariance matrix if diagonal_basis is False, else store the rotation matrix and eigenvalues
585595
"""
586596
# TODO: JtH, check if this includes the theory covmat
587-
covmat, diagonal_rotation, eig_vals = _covmat_prepared
597+
covmat, diagonal_rotation, eig_vals = _fiting_covmat
588598

589599
if not diagonal_basis:
590600
log.info("Saving fitting covmat")

0 commit comments

Comments
 (0)