Skip to content

Commit 6e80047

Browse files
committed
modify the ekos in memory
1 parent 3010e41 commit 6e80047

File tree

1 file changed

+34
-24
lines changed

1 file changed

+34
-24
lines changed

n3fit/src/evolven3fit/evolve.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections import defaultdict
2+
import dataclasses
23
import json
34
import logging
45
import pathlib
@@ -96,39 +97,50 @@ def evolve_fit(
9697
else:
9798
raise ValueError(f"dump_eko not provided and {eko_path=} not found")
9899

99-
# Assume the EKO can be used with no rotation and open it in read-only mode
100-
# inside a try-finally block to make sure the eko is closed at the end
101-
try:
102-
eko_op = eko.EKO.read(eko_path)
103-
104-
# Read the cards directly from the eko to make sure they are consistent
100+
# Open the EKO in read-only mode, if it needs to be manipulated keep it in memory
101+
with eko.EKO.read(eko_path) as eko_op:
102+
# Read the cards directly fro"m the eko to make sure they are consistent
105103
theory = eko_op.theory_card
106104
op = eko_op.operator_card
107105
# And dump them to the log
108106
_logger.debug(f"Theory card: {json.dumps(theory.raw)}")
109107
_logger.debug(f"Operator card: {json.dumps(op.raw)}")
110108

111-
# Check whether it needs to be modified
112-
eko_xgrid = eko_op.xgrid
113-
if XGrid(x_grid) != eko_xgrid:
114-
eko_op.close()
115-
eko_op = eko.EKO.edit(eko_path)
116-
117-
# This is a workaround for EKOS created with 0.13.4
118-
# in 0.13.4 the xgrid corresponds to the (internal) interpolation grid
119-
if eko_op.metadata.version == "0.13.4":
120-
# Prepare an "identity" rotation
121-
eko_xgrid = XGrid(x_grid)
122-
123-
for i, elem in eko_op.items():
124-
eko_op[i] = manipulate.xgrid_reshape(
109+
eko_original_xgrid = eko_op.xgrid
110+
if XGrid(x_grid) != eko_original_xgrid:
111+
# If the xgrid of the eko is not directly usable, construct a copy in memory
112+
# by replacing the internal inventory of operators in a readonly copy
113+
new_xgrid = XGrid(x_grid)
114+
new_metadata = dataclasses.replace(eko_op.metadata, xgrid=new_xgrid)
115+
116+
new_operators = {}
117+
for target_key in eko_op.operators:
118+
elem = eko_op[target_key.ep]
119+
120+
if eko_op.metadata.version == "0.13.4":
121+
# For eko 0.13.4 xgrid is the internal interpolation so we need to check
122+
# whether the rotation is truly needed
123+
# <in practice> this means checking whether the operator shape matches the grid
124+
oplen = elem.operator.shape[-1]
125+
if oplen != len(eko_original_xgrid):
126+
# The operator and its xgrid have different shape
127+
# either prepare an identity, or this EKO is not supported
128+
if oplen != len(x_grid):
129+
raise ValueError(
130+
f"The operator at {eko_path} is not usable, version not supported"
131+
)
132+
eko_original_xgrid = XGrid(x_grid)
133+
134+
new_operators[target_key] = manipulate.xgrid_reshape(
125135
elem,
126-
eko_xgrid,
136+
eko_original_xgrid,
127137
op.configs.interpolation_polynomial_degree,
128138
targetgrid=XGrid(x_grid),
129139
inputgrid=XGrid(x_grid),
130140
)
131-
eko_op.xgrid = XGrid(x_grid)
141+
142+
new_inventory = dataclasses.replace(eko_op.operators, cache=new_operators)
143+
eko_op = dataclasses.replace(eko_op, metadata=new_metadata, operators=new_inventory)
132144

133145
# Modify the info file with the fit-specific info
134146
info = info_file.build(theory, op, 1, info_update={})
@@ -178,8 +190,6 @@ def pdf_xq2(pid, x, Q2):
178190
)
179191
blocks.append(block)
180192
dump_evolved_replica(blocks, usr_path, replica + 1)
181-
finally:
182-
eko_op.close()
183193

184194
# remove folder:
185195
# The function dump_evolved_replica uses a temporary folder

0 commit comments

Comments
 (0)