diff --git a/docs/source/overview/prerequisites.rst b/docs/source/overview/prerequisites.rst index 05802e1c..f1ab340b 100644 --- a/docs/source/overview/prerequisites.rst +++ b/docs/source/overview/prerequisites.rst @@ -94,7 +94,9 @@ An example is the following:: polarized: False time_like: False n_integration_cores: 1 - mu0: 1.65 + init: + - 1.65 + - 4 mugrid: - - 50.0 - 5 diff --git a/src/pineko/check.py b/src/pineko/check.py index 3aebfc39..47c85771 100644 --- a/src/pineko/check.py +++ b/src/pineko/check.py @@ -111,9 +111,7 @@ def check_grid_and_eko_compatible(pineappl_grid, operators, xif, max_as, max_al) "Q2 grid in pineappl grid and eko operator are NOT compatible!" ) # x-grid - if not np.all( - in1d(np.unique(operators.bases.targetgrid.tolist()), np.array(x_grid)) - ): + if not np.all(in1d(np.unique(operators.xgrid.tolist()), np.array(x_grid))): raise ValueError("x grid in pineappl grid and eko operator are NOT compatible!") diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index ca6c1784..7c9c47d5 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -16,6 +16,8 @@ import rich.panel import yaml from eko import basis_rotation +from eko.interpolation import XGrid +from eko.io import manipulate from eko.io.types import ScaleVariationsMethod from eko.matchings import Atlas, nf_default from eko.quantities import heavy_quarks @@ -201,10 +203,12 @@ def write_operator_card(pineappl_grid, default_card, card_path, tcard): # update scale variation method operators_card["configs"]["scvar_method"] = sv_method - # Make sure that we are using the theory Q0 and fail if the template has a different one - operators_card["mu0"] = tcard["Q0"] - if default_card.get("mu0") is not None and default_card["mu0"] != tcard["Q0"]: - raise ValueError("Template declares a value of Q0 different from theory") + operators_card["init"] = (tcard["Q0"], tcard["nf0"]) + if default_card.get("init") is not None and default_card["init"] != [ + tcard["Q0"], + tcard["nf0"], + ]: + raise ValueError("Template declares a value of Q0, nf0 different from theory") q2_grid = (xif * xif * muf2_grid).tolist() masses = np.array([tcard["mc"], tcard["mb"], tcard["mt"]]) ** 2 @@ -361,32 +365,15 @@ def evolve_grid( if "integrability_version" in grid.key_values(): x_grid = np.append(x_grid, 1.0) - def xgrid_reshape(full_operator): - """Reinterpolate operators on output and/or input grids.""" - eko.io.manipulate.xgrid_reshape( - full_operator, targetgrid=eko.interpolation.XGrid(x_grid) - ) - check.check_grid_and_eko_compatible(grid, full_operator, xif, max_as, max_al) - # rotate to evolution (if doable and necessary) - if np.allclose(full_operator.bases.inputpids, br.flavor_basis_pids): - eko.io.manipulate.to_evol(full_operator) - # Here we are checking if the EKO contains the rotation matrix (flavor to evol) - elif not np.allclose( - full_operator.bases.inputpids, br.rotate_flavor_to_evolution - ): - raise ValueError("The EKO is neither in flavor nor in evolution basis.") - - xgrid_reshape(operators1) + check.check_grid_and_eko_compatible(grid, operators1, xif, max_as, max_al) if operators2 is not None: - xgrid_reshape(operators2) + check.check_grid_and_eko_compatible(grid, operators2, xif, max_as, max_al) # PineAPPL wants alpha_s = 4*pi*a_s # remember that we already accounted for xif in the opcard generation evmod = eko.couplings.couplings_mod_ev(opcard.configs.evolution_method) # Couplings ask for the square of the masses thresholds_ratios = np.power(tcard.heavy.matching_ratios, 2.0) - for q in range(tcard.couplings.max_num_flavs + 1, 6 + 1): - thresholds_ratios[q - 4] = np.inf sc = eko.couplings.Couplings( tcard.couplings, tcard.order, @@ -398,25 +385,31 @@ def xgrid_reshape(full_operator): # To compute the alphas values we are first reverting the factorization scale shift # and then obtaining the renormalization scale using xir. ren_grid2 = xir * xir * mur2_grid + nfgrid = [x[1] for x in operators1.operator_card.mugrid] alphas_values = [ - 4.0 - * np.pi - * sc.a_s( - mur2, - ) - for mur2 in ren_grid2 + 4.0 * np.pi * sc.a_s(mur2, nf_to=nf) for mur2, nf in zip(ren_grid2, nfgrid) ] + def xgrid_reshape(operator, operator_xgrid): + """Reinterpolate operators on output.""" + manipulate.xgrid_reshape( + operator, + operator_xgrid, + opcard.configs.interpolation_polynomial_degree, + targetgrid=XGrid(x_grid), + ) + def prepare(operator): """Match the raw operator with its relevant metadata.""" for (q2, _), op in operator.items(): + xgrid_reshape(op, operator.xgrid) info = PyOperatorSliceInfo( fac0=operator.mu20, - x0=operator.bases.inputgrid.raw, + x0=operator.xgrid.tolist(), pids0=basis_rotation.evol_basis_pids, fac1=q2, - x1=operator.bases.targetgrid.raw, - pids1=operator.bases.targetpids, + x1=operator.xgrid.tolist(), + pids1=basis_rotation.evol_basis_pids, pid_basis=PyPidBasis.Evol, ) yield (info, op.operator) diff --git a/tests/test_evolve.py b/tests/test_evolve.py index f529b80b..8c2fc653 100644 --- a/tests/test_evolve.py +++ b/tests/test_evolve.py @@ -52,20 +52,20 @@ def test_write_operator_card_q0(tmp_path): g = FakePine() t = copy.deepcopy(default_card) o = copy.deepcopy(example.raw_operator()) - # 1. Same Q0 and mu0, all ok + # 1. Same Q0 and init, all ok t["Q0"] = 5.0 - o["mu0"] = 5.0 + o["init"] = [5.0, 4] _xs, _mu2s = pineko.evolve.write_operator_card(g, o, p, t) with open(p, encoding="utf8") as f: oo = yaml.safe_load(f) - np.testing.assert_allclose(oo["mu0"], t["Q0"]) + np.testing.assert_allclose(oo["init"][0], t["Q0"]) # 2. Q0 only in theory, all ok - o.pop("mu0") + o.pop("init") _xs, _mu2s = pineko.evolve.write_operator_card(g, o, p, t) with open(p, encoding="utf8") as f: oo = yaml.safe_load(f) - np.testing.assert_allclose(oo["mu0"], t["Q0"]) + np.testing.assert_allclose(oo["init"][0], t["Q0"]) # 3. op is different, raises error - o["mu0"] = 11.0 + o["init"] = [11.0, 3] with pytest.raises(ValueError): _xs, _mu2s = pineko.evolve.write_operator_card(g, o, p, t)