|
27 | 27 |
|
28 | 28 | logger = logging.getLogger(__name__) |
29 | 29 |
|
| 30 | +# EKO marks any heavy quark flavor with index > nf as "intrinsic" (i.e. frozen, |
| 31 | +# identity-evolved) at every scale. However, intrinsic bottom and top must never |
| 32 | +# leak into the FK table, so their flavor-basis columns are masked whenever EKO |
| 33 | +# would otherwise treat them as intrinsic (flavor index > nf). Charm is excluded |
| 34 | +# here, since intrinsic charm is the supported feature. |
| 35 | +_INTRINSIC_HEAVY_FLAVOR_IDX = { |
| 36 | + 5: tuple(basis_rotation.flavor_basis_pids.index(pid) for pid in (-5, 5)), |
| 37 | + 6: tuple(basis_rotation.flavor_basis_pids.index(pid) for pid in (-6, 6)), |
| 38 | +} |
| 39 | + |
30 | 40 |
|
31 | 41 | def sv_scheme(tcard): |
32 | 42 | """Infere the factorization scale_variation scheme to be used from the theory card. |
@@ -479,14 +489,19 @@ def evolve_grid( |
479 | 489 |
|
480 | 490 | def prepare(operator, convolution_types): |
481 | 491 | """Match the raw operator with its relevant metadata.""" |
482 | | - for (q2, _), op in operator.items(): |
| 492 | + for (q2, nf), op in operator.items(): |
483 | 493 | # reshape the x-grid output |
484 | 494 | op = manipulate.xgrid_reshape( |
485 | 495 | op, |
486 | 496 | operator.xgrid, |
487 | 497 | opcard.configs.interpolation_polynomial_degree, |
488 | 498 | targetgrid=XGrid(x_grid), |
489 | 499 | ) |
| 500 | + # mask out intrinsic bottom/top before they get mixed into the |
| 501 | + # evolution basis by `to_evol` |
| 502 | + for intr_fl, flavor_idx in _INTRINSIC_HEAVY_FLAVOR_IDX.items(): |
| 503 | + if intr_fl > nf: |
| 504 | + op.operator[:, :, flavor_idx, :] = 0.0 |
490 | 505 | # rotate the input to evolution basis |
491 | 506 | op = manipulate.to_evol(op, source=True) |
492 | 507 | check.check_grid_and_eko_compatible(grid, x_grid, q2, xif, max_as, max_al) |
|
0 commit comments