From 8b43b5e437b8b69b7f945b09ab6d6c2328e7696a Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 12:14:03 +0100 Subject: [PATCH 01/12] added hessian to mc converter using watt thorne symmetric method --- validphys2/src/validphys/hessian2mc.py | 148 +++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 validphys2/src/validphys/hessian2mc.py diff --git a/validphys2/src/validphys/hessian2mc.py b/validphys2/src/validphys/hessian2mc.py new file mode 100644 index 0000000000..eaa590a401 --- /dev/null +++ b/validphys2/src/validphys/hessian2mc.py @@ -0,0 +1,148 @@ +""" +validphys.hessian2mc.py + +This module contains the functions that can be used to convert Hessian sets +like MSHT20 and CT18 to Monte Carlo sets. +The functions implemented here follow equations (4.3), for MSHT20, and (4.4), for CT18, +of the paper arXiv:2203.05506 +""" + +import pathlib +import lhapdf +import os +import logging +import numpy as np + +from validphys.core import PDF +from validphys.lhio import load_all_replicas, rep_matrix, write_replica + +log = logging.getLogger(__name__) + + +def write_new_lhapdf_info_file_from_previous_pdf( + path_old_pdfset, + name_old_pdfset, + path_new_pdfset, + name_new_pdfset, + num_members, + description_set="MC representation of hessian PDF set", + errortype="replicas", +): + """ + Writes a new LHAPDF set info file based on an existing set. + """ + + # write LHAPDF info file for a new pdf set + with open(path_old_pdfset / f"{name_old_pdfset}.info", "r") as in_stream, open( + path_new_pdfset / f"{name_new_pdfset}.info", "w" + ) as out_stream: + for l in in_stream.readlines(): + if l.find("SetDesc:") >= 0: + out_stream.write(f'SetDesc: f"{description_set}"\n') + elif l.find("NumMembers:") >= 0: + out_stream.write(f"NumMembers: {num_members}\n") + elif l.find("ErrorType:") >= 0: + out_stream.write(f"ErrorType: {errortype}\n") + else: + out_stream.write(l) + log.info(f"Info file written to {path_new_pdfset / f'{name_new_pdfset}.info'}") + + +def write_mc_watt_thorne_replicas(Rjk_std_normal, replicas_df, mc_pdf_path): + """ + Writes the Monte Carlo representation of a PDF set that is in Hessian form + using the Watt-Thorne (MSHT20) prescription described in Eq. 4.3 of arXiv:2203.05506. + + Parameters + ---------- + Rjk_std_normal: np.ndarray + Array of shape (num_members, n_eig) containing random standard normal numbers. + + replicas_df: pd.DataFrame + DataFrame containing replicas of the hessian set at all scales. + + mc_pdf_path: pathlib.Path + Path to the new Monte Carlo PDF set. + """ + + for i, rnd_std_norm_vec in enumerate(Rjk_std_normal): + + # Odd eigenvectors: negative direction, even eigenvectors: positive direction + df_odd = replicas_df.loc[:, 2::2] + df_even = replicas_df.loc[:, 3::2] + new_column_names = range(1, len(df_even.columns) + 1) + + df_even.columns = new_column_names + df_odd.columns = new_column_names + + central_member, hess_diff_cov = replicas_df.loc[:, [1]], df_even - df_odd + + # Eq. 4.3 of arXiv:2203.05506 + mc_replica = central_member.dot([1]) + 0.5 * hess_diff_cov.dot(rnd_std_norm_vec) + + wm_headers = f"PdfType: replica\nFormat: lhagrid1\nFromMCReplica: {i}\n" + log.info(f"Writing replica {i + 1} to {mc_pdf_path}") + write_replica(i + 1, mc_pdf_path, wm_headers.encode("UTF-8"), mc_replica) + + # Write central replica from hessian set to mc set + wm_headers = f"PdfType: replica\nFormat: lhagrid1\nFromMCReplica: {i}\n" + log.info(f"Writing central replica to {mc_pdf_path}") + write_replica(0, mc_pdf_path, wm_headers.encode("UTF-8"), central_member) + + +def write_hessian_to_mc_watt_thorne( + msht_like_hessian_pdf, + mc_pdf_name, + num_members, + watt_thorne_rnd_seed=1, +): + """ + Writes the Monte Carlo representation of a PDF set that is in Hessian form + using the Watt-Thorne (MSHT20) prescription described in Eq. 4.3 of arXiv:2203.05506. + + Parameters + ---------- + msht_like_hessian_pdf: str + The name of the Hessian PDF set that is to be converted to Monte Carlo. + + mc_pdf_name: str + The name of the new Monte Carlo PDF set. + + """ + hessian_set = PDF(msht_like_hessian_pdf) + + lhapdf_path = pathlib.Path(lhapdf.paths()[-1]) + + # path to hessian lhapdf set + hessian_pdf_path = lhapdf_path / msht_like_hessian_pdf + + # path to new wmin pdf set + mc_pdf_path = lhapdf_path / mc_pdf_name + + # create new wmin pdf set folder in lhapdf path if it does not exist + if not mc_pdf_path.exists(): + os.makedirs(mc_pdf_path) + + # write LHAPDF info file for new wmin pdf set + write_new_lhapdf_info_file_from_previous_pdf( + path_old_pdfset=hessian_pdf_path, + name_old_pdfset=msht_like_hessian_pdf, + path_new_pdfset=mc_pdf_path, + name_new_pdfset=mc_pdf_name, + num_members=num_members, + description_set=f"MC representation of {msht_like_hessian_pdf}", + errortype="replicas", + ) + + # load replicas from basis set at all scales + _, grids = load_all_replicas(hessian_set) + replicas_df = rep_matrix(grids) + + # Eg for MSHT20, mem=0 => central value; mem=1-64 => 32 eigenvector sets (+/- directions) + n_eig = int((replicas_df.shape[1] - 1) / 2) + + np.random.seed(watt_thorne_rnd_seed) + Rjk_std_normal = np.random.standard_normal(size=(num_members, n_eig)) + + # write replicas to new wmin pdf set + write_mc_watt_thorne_replicas(Rjk_std_normal, replicas_df, mc_pdf_path) From 999f50bb889ec7953f45a49c78901860341b562b Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 12:18:20 +0100 Subject: [PATCH 02/12] added tests for hessian 2 mc watt-thorne converter --- .../src/validphys/tests/test_hessian2mc.py | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 validphys2/src/validphys/tests/test_hessian2mc.py diff --git a/validphys2/src/validphys/tests/test_hessian2mc.py b/validphys2/src/validphys/tests/test_hessian2mc.py new file mode 100644 index 0000000000..a225a60dc4 --- /dev/null +++ b/validphys2/src/validphys/tests/test_hessian2mc.py @@ -0,0 +1,87 @@ +import numpy as np +import pandas as pd +from unittest import mock +from validphys.hessian2mc import write_mc_watt_thorne_replicas, write_hessian_to_mc_watt_thorne +import pathlib + + +@mock.patch("validphys.hessian2mc.write_replica") +@mock.patch("validphys.hessian2mc.log.info") +def test_write_mc_watt_thorne_replicas(mock_log_info, mock_write_replica): + # Set up mock inputs + n_eig = 5 + n_all_eig = 1 + 2 * n_eig # includes central member, so 1 + 2*n_eig + num_members = 50 # new MC members + num_nx_nq = 100 # xgrid and Q points + + replicas_df = pd.DataFrame( + np.random.standard_normal(size=(num_nx_nq, n_all_eig)), columns=range(1, n_all_eig + 1) + ) + + Rjk_std_normal = np.random.standard_normal(size=(num_members, n_eig)) + + # import IPython; IPython.embed() + mc_pdf_path = mock.Mock() # Mock the path + + # Call the function being tested + write_mc_watt_thorne_replicas(Rjk_std_normal, replicas_df, mc_pdf_path) + + # Verify that write_replica was called the correct number of times + assert ( + mock_write_replica.call_count == num_members + 1 + ) # for Rjk members + 1 for the central replica + + # Check if the log message was correct for the central replica + mock_log_info.assert_any_call(f"Writing central replica to {mc_pdf_path}") + + +@mock.patch("validphys.hessian2mc.write_mc_watt_thorne_replicas") +@mock.patch("validphys.hessian2mc.load_all_replicas") +@mock.patch("validphys.hessian2mc.rep_matrix") +@mock.patch("validphys.hessian2mc.write_new_lhapdf_info_file_from_previous_pdf") +@mock.patch("validphys.hessian2mc.os.makedirs") +@mock.patch("validphys.hessian2mc.lhapdf.paths") +@mock.patch("validphys.hessian2mc.PDF") +def test_write_hessian_to_mc_watt_thorne( + mock_pdf, + mock_lhapdf_paths, + mock_makedirs, + mock_write_info_file, + mock_rep_matrix, + mock_load_all_replicas, + mock_write_mc_replicas, +): + # Set up mock inputs + msht_like_hessian_pdf = "MSHT20" + mc_pdf_name = "MSHT20_MC" + num_members = 100 + + mock_load_all_replicas.return_value = (None, None) + + mock_pdf_instance = mock.Mock() + mock_pdf.return_value = mock_pdf_instance + + mock_lhapdf_paths.return_value = [pathlib.Path("/path/to/lhapdf")] + + mock_rep_matrix.return_value = np.random.randn(5, 7) # Mocked replica matrix + + # Call the function being tested + write_hessian_to_mc_watt_thorne(msht_like_hessian_pdf, mc_pdf_name, num_members) + + # Verify that the necessary directories were created + mc_pdf_path = pathlib.Path("/path/to/lhapdf") / mc_pdf_name + mock_makedirs.assert_called_once_with(mc_pdf_path) + + # Verify that the LHAPDF info file was written + mock_write_info_file.assert_called_once_with( + path_old_pdfset=pathlib.Path("/path/to/lhapdf") / msht_like_hessian_pdf, + name_old_pdfset=msht_like_hessian_pdf, + path_new_pdfset=mc_pdf_path, + name_new_pdfset=mc_pdf_name, + num_members=num_members, + description_set=f"MC representation of {msht_like_hessian_pdf}", + errortype="replicas", + ) + + # Verify that the replicas were written + mock_write_mc_replicas.assert_called_once() From 8d9ce9488f3edcd582838b4047b23c8d1935870a Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 12:25:04 +0100 Subject: [PATCH 03/12] added hessian2mc to app --- validphys2/src/validphys/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/validphys2/src/validphys/app.py b/validphys2/src/validphys/app.py index 8073566389..42cf0def31 100644 --- a/validphys2/src/validphys/app.py +++ b/validphys2/src/validphys/app.py @@ -52,6 +52,7 @@ "validphys.mc2hessian", "reportengine.report", "validphys.overfit_metric", + "validphys.hessian2mc", ] log = logging.getLogger(__name__) From f106afc682fb5d153a9192b398179f8a3377cc5c Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 12:30:08 +0100 Subject: [PATCH 04/12] added hessian type pdf check --- validphys2/src/validphys/checks.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/validphys2/src/validphys/checks.py b/validphys2/src/validphys/checks.py index 8ccecdec43..645c37bb88 100644 --- a/validphys2/src/validphys/checks.py +++ b/validphys2/src/validphys/checks.py @@ -42,6 +42,15 @@ def check_pdf_is_montecarlo_or_hessian(pdf, **kwargs): ) +@make_argcheck +def check_pdf_is_hessian(pdf, **kwargs): + etype = pdf.error_type + check( + etype in {'symmhessian', 'hessian'}, + f"Error type of PDF {pdf} must be 'symmhessian' or 'hessian' and not '{etype}'", + ) + + @make_argcheck def check_using_theory_covmat(use_theorycovmat): """Check that the `use_theorycovmat` is set to True""" From c6594b7a86eb526a9729c280caabb68c1b908298 Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 12:31:01 +0100 Subject: [PATCH 05/12] added check to write functioun --- validphys2/src/validphys/hessian2mc.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/validphys2/src/validphys/hessian2mc.py b/validphys2/src/validphys/hessian2mc.py index eaa590a401..3bcf0e0756 100644 --- a/validphys2/src/validphys/hessian2mc.py +++ b/validphys2/src/validphys/hessian2mc.py @@ -13,8 +13,8 @@ import logging import numpy as np -from validphys.core import PDF from validphys.lhio import load_all_replicas, rep_matrix, write_replica +from validphys.checks import check_pdf_is_hessian log = logging.getLogger(__name__) @@ -90,31 +90,27 @@ def write_mc_watt_thorne_replicas(Rjk_std_normal, replicas_df, mc_pdf_path): write_replica(0, mc_pdf_path, wm_headers.encode("UTF-8"), central_member) -def write_hessian_to_mc_watt_thorne( - msht_like_hessian_pdf, - mc_pdf_name, - num_members, - watt_thorne_rnd_seed=1, -): +@check_pdf_is_hessian +def write_hessian_to_mc_watt_thorne(pdf, mc_pdf_name, num_members, watt_thorne_rnd_seed=1): """ Writes the Monte Carlo representation of a PDF set that is in Hessian form using the Watt-Thorne (MSHT20) prescription described in Eq. 4.3 of arXiv:2203.05506. Parameters ---------- - msht_like_hessian_pdf: str - The name of the Hessian PDF set that is to be converted to Monte Carlo. + pdf: validphys.core.PDF + The Hessian PDF set that is to be converted to Monte Carlo. mc_pdf_name: str The name of the new Monte Carlo PDF set. """ - hessian_set = PDF(msht_like_hessian_pdf) + hessian_set = pdf lhapdf_path = pathlib.Path(lhapdf.paths()[-1]) # path to hessian lhapdf set - hessian_pdf_path = lhapdf_path / msht_like_hessian_pdf + hessian_pdf_path = lhapdf_path / str(hessian_set) # path to new wmin pdf set mc_pdf_path = lhapdf_path / mc_pdf_name @@ -126,11 +122,11 @@ def write_hessian_to_mc_watt_thorne( # write LHAPDF info file for new wmin pdf set write_new_lhapdf_info_file_from_previous_pdf( path_old_pdfset=hessian_pdf_path, - name_old_pdfset=msht_like_hessian_pdf, + name_old_pdfset=str(hessian_set), path_new_pdfset=mc_pdf_path, name_new_pdfset=mc_pdf_name, num_members=num_members, - description_set=f"MC representation of {msht_like_hessian_pdf}", + description_set=f"MC representation of {str(hessian_set)}", errortype="replicas", ) From 400c2b8675eaaf4c3d9dbff6c0d849d1a4b7c866 Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 12:31:44 +0100 Subject: [PATCH 06/12] added example runcard --- validphys2/examples/hessian_2mc.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 validphys2/examples/hessian_2mc.yaml diff --git a/validphys2/examples/hessian_2mc.yaml b/validphys2/examples/hessian_2mc.yaml new file mode 100644 index 0000000000..b796f4ee2c --- /dev/null +++ b/validphys2/examples/hessian_2mc.yaml @@ -0,0 +1,16 @@ +meta: + author: Mark N. Costantini + title: runcard for conversion of msht20 hessian set to MC + keywords: [wmin basis] + + +pdf: MSTW2008nlo68cl + +mc_pdf_name: MSTW2008nlo68cl_mc + +num_members: 100 + +watt_thorne_rnd_seed: 1 + +actions_: + - write_hessian_to_mc_watt_thorne From 9184f3270182402b115264156199ab96adeeb0b2 Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 14:06:04 +0100 Subject: [PATCH 07/12] removed mocked pdf instance --- validphys2/src/validphys/tests/test_hessian2mc.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/validphys2/src/validphys/tests/test_hessian2mc.py b/validphys2/src/validphys/tests/test_hessian2mc.py index a225a60dc4..68f55fa695 100644 --- a/validphys2/src/validphys/tests/test_hessian2mc.py +++ b/validphys2/src/validphys/tests/test_hessian2mc.py @@ -41,9 +41,7 @@ def test_write_mc_watt_thorne_replicas(mock_log_info, mock_write_replica): @mock.patch("validphys.hessian2mc.write_new_lhapdf_info_file_from_previous_pdf") @mock.patch("validphys.hessian2mc.os.makedirs") @mock.patch("validphys.hessian2mc.lhapdf.paths") -@mock.patch("validphys.hessian2mc.PDF") def test_write_hessian_to_mc_watt_thorne( - mock_pdf, mock_lhapdf_paths, mock_makedirs, mock_write_info_file, @@ -58,9 +56,6 @@ def test_write_hessian_to_mc_watt_thorne( mock_load_all_replicas.return_value = (None, None) - mock_pdf_instance = mock.Mock() - mock_pdf.return_value = mock_pdf_instance - mock_lhapdf_paths.return_value = [pathlib.Path("/path/to/lhapdf")] mock_rep_matrix.return_value = np.random.randn(5, 7) # Mocked replica matrix From e3e073301283c263bfea27ba2b86d6433945c732 Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 14:27:34 +0100 Subject: [PATCH 08/12] remove ErrorConfLevel line when writing a replicas errortype from a hessian --- validphys2/src/validphys/hessian2mc.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/validphys2/src/validphys/hessian2mc.py b/validphys2/src/validphys/hessian2mc.py index 3bcf0e0756..74ba38606c 100644 --- a/validphys2/src/validphys/hessian2mc.py +++ b/validphys2/src/validphys/hessian2mc.py @@ -43,6 +43,9 @@ def write_new_lhapdf_info_file_from_previous_pdf( out_stream.write(f"NumMembers: {num_members}\n") elif l.find("ErrorType:") >= 0: out_stream.write(f"ErrorType: {errortype}\n") + elif l.find("ErrorConfLevel") >= 0: + # remove ErrorConfLevel line + pass else: out_stream.write(l) log.info(f"Info file written to {path_new_pdfset / f'{name_new_pdfset}.info'}") From 14f464d3a64399bf990c66763256c1641aff8192 Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 15:08:26 +0100 Subject: [PATCH 09/12] added hessian2mc to index --- doc/sphinx/source/tutorials/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/sphinx/source/tutorials/index.rst b/doc/sphinx/source/tutorials/index.rst index a9902db814..c6c20abf63 100644 --- a/doc/sphinx/source/tutorials/index.rst +++ b/doc/sphinx/source/tutorials/index.rst @@ -47,6 +47,7 @@ Special PDF sets ./reproduce ./bundle-pdfs.rst ./mc2hessian.rst + ./hessian2mc.rst Miscellaneous ------------- From 63bf5cadbc2fdc7dad6d4c2310ddef4aaab1859a Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 15:08:48 +0100 Subject: [PATCH 10/12] added hessian2mc rst file --- doc/sphinx/source/tutorials/hessian2mc.rst | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 doc/sphinx/source/tutorials/hessian2mc.rst diff --git a/doc/sphinx/source/tutorials/hessian2mc.rst b/doc/sphinx/source/tutorials/hessian2mc.rst new file mode 100644 index 0000000000..344bece3ab --- /dev/null +++ b/doc/sphinx/source/tutorials/hessian2mc.rst @@ -0,0 +1,33 @@ +.. _hessian2mc: +How to transform a Hessian set into the corresponding Monte Carlo PDF +===================================================================== + +A Hessian PDF set can be transformed into a Monte Carlo replica set using the +method described in Eq. (4.3) of `PDF4LHC21 `_ using a runcard +like the one below. +In this example ``Neig`` are the number of basis eigenvectors of the Hessian PDF. +``mc_pdf_name`` is the name of the new MC replica set that will be created. +``watt_thorne_rnd_seed`` is the random seed used to generate the MC replicas as shown in the equation below. + +.. math:: + + f^{MC, (k)}(x,Q) = f^{H}_{0}(x,Q) + \frac{1}{2} \sum_{j=1}^{Neig} \left(f^{H}_{j,+}(x,Q) - f^{H}_{j,-}(x,Q)\right) R_j^{(k)} + +where :math:`f^{MC, (k)}(x,Q)` is the :math:`k`-th Monte Carlo replica, :math:`f^{H}_{0}(x,Q)` the central Hessian member, +:math:`f^{H}_{j,\pm}(x,Q)` the positive and negative eigenvector directions corresponding to the :math:`j`-th Hessian eigenvector, and :math:`R_j^{(k)}` +are random standard normal numbers. + +The new MC replica set will be saved in the LHAPDF folder. + +.. code:: yaml + + pdf: MSTW2008nlo68cl + + mc_pdf_name: MSTW2008nlo68cl_mc + + num_members: 100 + + watt_thorne_rnd_seed: 1 + + actions_: + - write_hessian_to_mc_watt_thorne From 53d4ceb2175aef155620d33f1c8c206b5e635cfb Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Mon, 14 Oct 2024 15:10:09 +0100 Subject: [PATCH 11/12] updated meta name to Lazy person --- validphys2/examples/hessian_2mc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/validphys2/examples/hessian_2mc.yaml b/validphys2/examples/hessian_2mc.yaml index b796f4ee2c..6a3cf4c895 100644 --- a/validphys2/examples/hessian_2mc.yaml +++ b/validphys2/examples/hessian_2mc.yaml @@ -1,7 +1,7 @@ meta: - author: Mark N. Costantini + author: Lazy Person title: runcard for conversion of msht20 hessian set to MC - keywords: [wmin basis] + keywords: [hessian Monte carlo] pdf: MSTW2008nlo68cl From 8f3bf6293817fd9f64e71f38db74f3551b0c0f69 Mon Sep 17 00:00:00 2001 From: Mark Nestor Costantini Date: Fri, 18 Oct 2024 23:12:57 +0100 Subject: [PATCH 12/12] implemented Roy's comments --- validphys2/src/validphys/hessian2mc.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/validphys2/src/validphys/hessian2mc.py b/validphys2/src/validphys/hessian2mc.py index 74ba38606c..c9361c7156 100644 --- a/validphys2/src/validphys/hessian2mc.py +++ b/validphys2/src/validphys/hessian2mc.py @@ -3,8 +3,7 @@ This module contains the functions that can be used to convert Hessian sets like MSHT20 and CT18 to Monte Carlo sets. -The functions implemented here follow equations (4.3), for MSHT20, and (4.4), for CT18, -of the paper arXiv:2203.05506 +The functions implemented here follow equations (4.3) of the paper arXiv:2203.05506 """ import pathlib @@ -38,9 +37,9 @@ def write_new_lhapdf_info_file_from_previous_pdf( ) as out_stream: for l in in_stream.readlines(): if l.find("SetDesc:") >= 0: - out_stream.write(f'SetDesc: f"{description_set}"\n') + out_stream.write(f'SetDesc: "{description_set}"\n') elif l.find("NumMembers:") >= 0: - out_stream.write(f"NumMembers: {num_members}\n") + out_stream.write(f"NumMembers: {num_members+1}\n") elif l.find("ErrorType:") >= 0: out_stream.write(f"ErrorType: {errortype}\n") elif l.find("ErrorConfLevel") >= 0: @@ -54,7 +53,7 @@ def write_new_lhapdf_info_file_from_previous_pdf( def write_mc_watt_thorne_replicas(Rjk_std_normal, replicas_df, mc_pdf_path): """ Writes the Monte Carlo representation of a PDF set that is in Hessian form - using the Watt-Thorne (MSHT20) prescription described in Eq. 4.3 of arXiv:2203.05506. + using the Watt-Thorne prescription described in Eq. 4.3 of arXiv:2203.05506. Parameters ---------- @@ -83,14 +82,13 @@ def write_mc_watt_thorne_replicas(Rjk_std_normal, replicas_df, mc_pdf_path): # Eq. 4.3 of arXiv:2203.05506 mc_replica = central_member.dot([1]) + 0.5 * hess_diff_cov.dot(rnd_std_norm_vec) - wm_headers = f"PdfType: replica\nFormat: lhagrid1\nFromMCReplica: {i}\n" - log.info(f"Writing replica {i + 1} to {mc_pdf_path}") - write_replica(i + 1, mc_pdf_path, wm_headers.encode("UTF-8"), mc_replica) + headers = f"PdfType: replica\nFormat: lhagrid1\nFromHessReplica: {i}\n" + write_replica(i + 1, mc_pdf_path, headers.encode("UTF-8"), mc_replica) # Write central replica from hessian set to mc set - wm_headers = f"PdfType: replica\nFormat: lhagrid1\nFromMCReplica: {i}\n" + headers = f"PdfType: replica\nFormat: lhagrid1\nFromHessReplica: {i}\n" log.info(f"Writing central replica to {mc_pdf_path}") - write_replica(0, mc_pdf_path, wm_headers.encode("UTF-8"), central_member) + write_replica(0, mc_pdf_path, headers.encode("UTF-8"), central_member) @check_pdf_is_hessian @@ -115,14 +113,14 @@ def write_hessian_to_mc_watt_thorne(pdf, mc_pdf_name, num_members, watt_thorne_r # path to hessian lhapdf set hessian_pdf_path = lhapdf_path / str(hessian_set) - # path to new wmin pdf set + # path to new pdf set mc_pdf_path = lhapdf_path / mc_pdf_name - # create new wmin pdf set folder in lhapdf path if it does not exist + # create new pdf set folder in lhapdf path if it does not exist if not mc_pdf_path.exists(): os.makedirs(mc_pdf_path) - # write LHAPDF info file for new wmin pdf set + # write LHAPDF info file for new pdf set write_new_lhapdf_info_file_from_previous_pdf( path_old_pdfset=hessian_pdf_path, name_old_pdfset=str(hessian_set), @@ -143,5 +141,5 @@ def write_hessian_to_mc_watt_thorne(pdf, mc_pdf_name, num_members, watt_thorne_r np.random.seed(watt_thorne_rnd_seed) Rjk_std_normal = np.random.standard_normal(size=(num_members, n_eig)) - # write replicas to new wmin pdf set + # write replicas to new pdf set write_mc_watt_thorne_replicas(Rjk_std_normal, replicas_df, mc_pdf_path)