From bb523b4cf7553bc393e7b58e7f064c138f075c41 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 16:06:35 +0200 Subject: [PATCH 01/67] Add mypy --- .pre-commit-config.yaml | 7 +++++++ benchmarks/__init__.py | 0 benchmarks/ekobox/__init__.py | 0 pyproject.toml | 7 +++++++ 4 files changed, 14 insertions(+) create mode 100644 benchmarks/__init__.py create mode 100644 benchmarks/ekobox/__init__.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7ebbb534b..0a34b041f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,6 +42,13 @@ repos: args: ["--add-ignore=D107,D105"] additional_dependencies: - toml + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.4.1 + hooks: + - id: mypy + additional_dependencies: [types-PyYAML] + pass_filenames: false + args: [".", "--ignore-missing-imports"] - repo: https://github.com/pre-commit/pre-commit rev: v3.3.3 hooks: diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/benchmarks/ekobox/__init__.py b/benchmarks/ekobox/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pyproject.toml b/pyproject.toml index 31be6cb0c..1f7d239c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -171,3 +171,10 @@ max-args = 10 [tool.pydocstyle] convention = "numpy" + +[tool.mypy] +exclude = [ + 'extras/', + 'benchmarks/env', + 'doc/', +] From 103567c5c3a508bb57a4a615e4cf5f794ada9c5d Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 16:39:43 +0200 Subject: [PATCH 02/67] Restrict mypy and start fixing --- .pre-commit-config.yaml | 2 +- pyproject.toml | 7 ------- src/eko/couplings.py | 5 +++-- src/eko/evolution_operator/__init__.py | 3 ++- src/eko/evolution_operator/grid.py | 4 ++-- src/eko/quantities/couplings.py | 3 +-- 6 files changed, 9 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0a34b041f..a8dc75857 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: mypy additional_dependencies: [types-PyYAML] pass_filenames: false - args: [".", "--ignore-missing-imports"] + args: ["--ignore-missing-imports", "src/"] - repo: https://github.com/pre-commit/pre-commit rev: v3.3.3 hooks: diff --git a/pyproject.toml b/pyproject.toml index 1f7d239c5..31be6cb0c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -171,10 +171,3 @@ max-args = 10 [tool.pydocstyle] convention = "numpy" - -[tool.mypy] -exclude = [ - 'extras/', - 'benchmarks/env', - 'doc/', -] diff --git a/src/eko/couplings.py b/src/eko/couplings.py index b0d39a070..1b3620032 100644 --- a/src/eko/couplings.py +++ b/src/eko/couplings.py @@ -8,10 +8,11 @@ """ import logging -from typing import Iterable, List +from typing import Dict, Iterable, List, Tuple import numba as nb import numpy as np +import numpy.typing as npt import scipy from . import constants, matchings @@ -474,7 +475,7 @@ def assert_positive(name, var): self.decoupled_running, ) # cache - self.cache = {} + self.cache: Dict[Tuple[float, float, int, float, float], npt.NDArray] = {} @property def mu2_ref(self): diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index eab3c64de..6a49551a5 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -8,6 +8,7 @@ import os import time from multiprocessing import Pool +from typing import Dict, Tuple import numba as nb import numpy as np @@ -617,7 +618,7 @@ def __init__( # TODO make 'cut' external parameter? self._mellin_cut = mellin_cut self.is_threshold = is_threshold - self.op_members = {} + self.op_members: Dict[Tuple[int, int], OpMember] = {} self.order = tuple(config["order"]) self.alphaem_running = self.managers["couplings"].alphaem_running if self.log_label == "Evolution": diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index ca8a46d51..ad97f6e42 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -6,7 +6,7 @@ """ import logging from dataclasses import astuple -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional import numpy as np import numpy.typing as npt @@ -61,7 +61,7 @@ def __init__( interpol_dispatcher: InterpolatorDispatcher, ): # check - config = {} + config: Dict[str, Any] = {} config["order"] = order config["intrinsic_range"] = intrinsic_flavors config["xif2"] = xif**2 diff --git a/src/eko/quantities/couplings.py b/src/eko/quantities/couplings.py index 449abab38..01b11d138 100644 --- a/src/eko/quantities/couplings.py +++ b/src/eko/quantities/couplings.py @@ -1,7 +1,6 @@ """Types and quantities related to theory couplings.""" import dataclasses import enum -from typing import Optional from ..io.dictlike import DictLike from ..io.types import FlavorsNumber, LinearScale, ReferenceRunning, Scalar @@ -22,7 +21,7 @@ class CouplingsInfo(DictLike): alphaem: Coupling scale: LinearScale max_num_flavs: FlavorsNumber - num_flavs_ref: Optional[FlavorsNumber] + num_flavs_ref: FlavorsNumber r"""Number of active flavors at strong coupling reference scale. I.e. :math:`n_{f,\text{ref}}(\mu^2_{\text{ref}})`, formerly called From e7b6e9360390e0224664b2faf6e21f9327f15a12 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 16:58:36 +0200 Subject: [PATCH 03/67] Start fixing tests for num_flavs_ref=None --- tests/eko/quantities/test_couplings.py | 2 +- tests/eko/test_couplings.py | 28 ++++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/eko/quantities/test_couplings.py b/tests/eko/quantities/test_couplings.py index 0a3b97415..00ccae9d1 100644 --- a/tests/eko/quantities/test_couplings.py +++ b/tests/eko/quantities/test_couplings.py @@ -3,7 +3,7 @@ def test_couplings_ref(): scale = 90.0 - d = dict(alphas=0.1, alphaem=0.01, scale=scale, max_num_flavs=6, num_flavs_ref=None) + d = dict(alphas=0.1, alphaem=0.01, scale=scale, max_num_flavs=6, num_flavs_ref=5) couplings = CouplingsInfo.from_dict(d) assert couplings.scale == scale assert not couplings.em_running diff --git a/tests/eko/test_couplings.py b/tests/eko/test_couplings.py index 62110da16..646a56448 100644 --- a/tests/eko/test_couplings.py +++ b/tests/eko/test_couplings.py @@ -54,7 +54,7 @@ def test_init(self): alphas=alpharef[0], alphaem=alpharef[1], scale=muref, - num_flavs_ref=None, + num_flavs_ref=5, max_num_flavs=6, ) ) @@ -152,18 +152,19 @@ def test_ref(self): (0, np.inf, np.inf), (2, 4, 175), ] + nfrefs = (3, 4, 5) alpharef = (0.118, 0.00781) muref = 91.0 - couplings = CouplingsInfo.from_dict( - dict( - alphas=alpharef[0], - alphaem=alpharef[1], - scale=muref, - num_flavs_ref=None, - max_num_flavs=6, + for thresh_setup, nfref in zip(thresh_setups, nfrefs): + couplings = CouplingsInfo.from_dict( + dict( + alphas=alpharef[0], + alphaem=alpharef[1], + scale=muref, + num_flavs_ref=nfref, + max_num_flavs=6, + ) ) - ) - for thresh_setup in thresh_setups: for order_s in [1, 2, 3, 4]: for order_em in [0, 1, 2]: for evmod in CouplingEvolutionMethod: @@ -220,9 +221,10 @@ def test_exact(self): (0, np.inf, np.inf), (2, 4, 175), ] + nfrefs = (3, 4, 5) alpharef = np.array([0.118, 0.00781]) muref = 91.0 - for thresh_setup in thresh_setups: + for thresh_setup, nfref in zip(thresh_setups, nfrefs): for qcd in range(1, 4 + 1): for qed in range(2 + 1): for em_running in [ @@ -235,7 +237,7 @@ def test_exact(self): alphas=alpharef[0], alphaem=alpharef[1], scale=muref, - num_flavs_ref=None, + num_flavs_ref=nfref, max_num_flavs=6, em_running=em_running, ) @@ -298,7 +300,7 @@ def benchmark_expanded_n3lo(self): alphas=alpharef[0], alphaem=alpharef[1], scale=muref, - num_flavs_ref=None, + num_flavs_ref=5, max_num_flavs=6, ) m2c = 2 From bbfc166bd1e8a8fefaaf1e4c6c0e4907a5af3ca8 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 17:28:05 +0200 Subject: [PATCH 04/67] Apply more mypy fixes --- src/eko/evolution_operator/__init__.py | 4 ++-- .../operator_matrix_element.py | 3 ++- src/eko/io/inventory.py | 4 ++-- src/eko/io/struct.py | 22 +++++++++---------- src/eko/msbar_masses.py | 2 +- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 6a49551a5..4251c5a4e 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -604,8 +604,8 @@ class Operator(sv.ModeMixin): log_label = "Evolution" # complete list of possible evolution operators labels - full_labels = br.full_labels - full_labels_qed = br.full_unified_labels + full_labels = list(br.full_labels) + full_labels_qed = list(br.full_unified_labels) def __init__( self, config, managers, segment: Segment, mellin_cut=5e-2, is_threshold=False diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 5696ead19..809279c77 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -3,6 +3,7 @@ import copy import functools import logging +from typing import List, Tuple import numba as nb import numpy as np @@ -208,7 +209,7 @@ class OperatorMatrixElement(Operator): (br.matching_hminus_pid, br.matching_hminus_pid), ] # still valid in QED since Sdelta and Vdelta matchings are diagonal - full_labels_qed = copy.deepcopy(full_labels) + full_labels_qed: List[Tuple[int, int]] = copy.deepcopy(full_labels) def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): super().__init__(config, managers, Segment(q2, q2, nf)) diff --git a/src/eko/io/inventory.py b/src/eko/io/inventory.py index efdd2e9b0..d22046c76 100644 --- a/src/eko/io/inventory.py +++ b/src/eko/io/inventory.py @@ -2,7 +2,7 @@ import base64 from dataclasses import asdict, dataclass, field from pathlib import Path -from typing import Dict, Generic, Optional, Type, TypeVar +from typing import Dict, Generic, Literal, Optional, Type, TypeVar import yaml @@ -10,7 +10,7 @@ from .items import Header, Operator NBYTES = 8 -ENDIANNESS = "little" +ENDIANNESS: Literal["little", "big"] = "little" HEADER_EXT = ".yaml" ARRAY_EXT = [".npy", ".npz"] diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index fecba3c57..3185c71ef 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -373,17 +373,17 @@ def open(cls, path: os.PathLike, mode="r"): raise ValueError(f"Unknown file mode: {mode}") tmpdir = pathlib.Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) - if load: - cls.load(path, tmpdir) - metadata = Metadata.load(tmpdir) - opened = cls( - **inventories(tmpdir, access), - metadata=metadata, - access=access, - ) - opened.operators.sync() - else: - opened = Builder(path=tmpdir, access=access) + if not load: + return Builder(path=tmpdir, access=access) + # load existing instead + cls.load(path, tmpdir) + metadata = Metadata.load(tmpdir) + opened: EKO = cls( + **inventories(tmpdir, access), + metadata=metadata, + access=access, + ) + opened.operators.sync() return opened diff --git a/src/eko/msbar_masses.py b/src/eko/msbar_masses.py index 356a81019..c72893fc3 100644 --- a/src/eko/msbar_masses.py +++ b/src/eko/msbar_masses.py @@ -395,7 +395,7 @@ def sc(thr_masses): heavy_quarks = quark_names[3:] hq_idxs = np.arange(0, 3) if nf_ref > 4: - heavy_quarks = reversed(heavy_quarks) + heavy_quarks = str(reversed(heavy_quarks)) hq_idxs = reversed(hq_idxs) # loop on heavy quarks and compute the msbar masses From 2d8d8bf55c6be567701a6db02dc66948d667595b Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 17:55:27 +0200 Subject: [PATCH 05/67] Apply more mypy fixes 2 --- src/eko/evolution_operator/__init__.py | 5 ++++- src/eko/evolution_operator/grid.py | 11 +++++------ src/eko/msbar_masses.py | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 4251c5a4e..0f9c52c4f 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -579,6 +579,9 @@ def quad_ker_qed( return ker +OPMEMBERS = Dict[Tuple[int, int], OpMember] + + class Operator(sv.ModeMixin): """Internal representation of a single EKO. @@ -618,7 +621,7 @@ def __init__( # TODO make 'cut' external parameter? self._mellin_cut = mellin_cut self.is_threshold = is_threshold - self.op_members: Dict[Tuple[int, int], OpMember] = {} + self.op_members: OPMEMBERS = {} self.order = tuple(config["order"]) self.alphaem_running = self.managers["couplings"].alphaem_running if self.log_label == "Evolution": diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index ad97f6e42..af478be9e 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -5,7 +5,6 @@ """ import logging -from dataclasses import astuple from typing import Any, Dict, List, Optional import numpy as np @@ -17,9 +16,9 @@ from ..interpolation import InterpolatorDispatcher from ..io.runcards import Configs, Debug from ..io.types import EvolutionPoint as EPoint -from ..io.types import Order +from ..io.types import Order, SquaredScale from ..matchings import Atlas, Segment, flavor_shift, is_downward_path -from . import Operator, flavors, matching_condition, physical +from . import OPMEMBERS, Operator, flavors, matching_condition, physical from .operator_matrix_element import OperatorMatrixElement logger = logging.getLogger(__name__) @@ -95,8 +94,8 @@ def __init__( couplings=couplings, interpol_dispatcher=interpol_dispatcher, ) - self._threshold_operators = {} - self._matching_operators = {} + self._threshold_operators: Dict[Segment, Operator] = {} + self._matching_operators: Dict[SquaredScale, OPMEMBERS] = {} def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: """Generate the threshold operators. @@ -118,7 +117,7 @@ def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: is_downward = is_downward_path(path) shift = flavor_shift(is_downward) for seg in path[:-1]: - new_op_key = astuple(seg) + new_op_key = seg kthr = self.config["thresholds_ratios"][seg.nf - shift] ome = OperatorMatrixElement( self.config, diff --git a/src/eko/msbar_masses.py b/src/eko/msbar_masses.py index c72893fc3..f13582110 100644 --- a/src/eko/msbar_masses.py +++ b/src/eko/msbar_masses.py @@ -395,7 +395,7 @@ def sc(thr_masses): heavy_quarks = quark_names[3:] hq_idxs = np.arange(0, 3) if nf_ref > 4: - heavy_quarks = str(reversed(heavy_quarks)) + heavy_quarks = "".join([e for e in reversed(heavy_quarks)]) hq_idxs = reversed(hq_idxs) # loop on heavy quarks and compute the msbar masses From 494da3c0ccd3d081cc3e345f39e96457b0fd46a3 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 18:02:56 +0200 Subject: [PATCH 06/67] Rename OpMembers --- src/eko/evolution_operator/__init__.py | 4 ++-- src/eko/evolution_operator/grid.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 0f9c52c4f..d079bed3d 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -579,7 +579,7 @@ def quad_ker_qed( return ker -OPMEMBERS = Dict[Tuple[int, int], OpMember] +OpMembers = Dict[Tuple[int, int], OpMember] class Operator(sv.ModeMixin): @@ -621,7 +621,7 @@ def __init__( # TODO make 'cut' external parameter? self._mellin_cut = mellin_cut self.is_threshold = is_threshold - self.op_members: OPMEMBERS = {} + self.op_members: OpMembers = {} self.order = tuple(config["order"]) self.alphaem_running = self.managers["couplings"].alphaem_running if self.log_label == "Evolution": diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index af478be9e..5035b22b2 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -18,7 +18,7 @@ from ..io.types import EvolutionPoint as EPoint from ..io.types import Order, SquaredScale from ..matchings import Atlas, Segment, flavor_shift, is_downward_path -from . import OPMEMBERS, Operator, flavors, matching_condition, physical +from . import Operator, OpMembers, flavors, matching_condition, physical from .operator_matrix_element import OperatorMatrixElement logger = logging.getLogger(__name__) @@ -95,7 +95,7 @@ def __init__( interpol_dispatcher=interpol_dispatcher, ) self._threshold_operators: Dict[Segment, Operator] = {} - self._matching_operators: Dict[SquaredScale, OPMEMBERS] = {} + self._matching_operators: Dict[SquaredScale, OpMembers] = {} def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: """Generate the threshold operators. From 48ac90e43ae60e37af173d5db15f36e2caf0f2fb Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 18:22:05 +0200 Subject: [PATCH 07/67] Fix mypy in io/legacy --- src/eko/io/legacy.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/eko/io/legacy.py b/src/eko/io/legacy.py index 1df9941b1..c7799d0fb 100644 --- a/src/eko/io/legacy.py +++ b/src/eko/io/legacy.py @@ -12,15 +12,19 @@ import numpy as np import yaml -from eko.interpolation import XGrid -from eko.io.runcards import flavored_mugrid -from eko.quantities.heavy_quarks import HeavyInfo, HeavyQuarkMasses, MatchingRatios - +from ..interpolation import XGrid +from ..io.runcards import flavored_mugrid +from ..quantities.heavy_quarks import ( + HeavyInfo, + HeavyQuarkMasses, + MatchingRatios, + QuarkMassScheme, +) from . import raw from .dictlike import DictLike from .struct import EKO, Operator from .types import EvolutionPoint as EPoint -from .types import RawCard +from .types import RawCard, ReferenceRunning def load_tar(source: os.PathLike, dest: os.PathLike, errors: bool = False): @@ -38,8 +42,8 @@ def load_tar(source: os.PathLike, dest: os.PathLike, errors: bool = False): whether to load also errors (default ``False``) """ - with tempfile.TemporaryDirectory() as tmpdir: - tmpdir = pathlib.Path(tmpdir) + with tempfile.TemporaryDirectory() as tmpdirr: + tmpdir = pathlib.Path(tmpdirr) with tarfile.open(source, "r") as tar: raw.safe_extractall(tar, tmpdir) @@ -92,10 +96,16 @@ def from_old(cls, old: RawCard): """Load from old metadata.""" heavy = HeavyInfo( num_flavs_init=4, - num_flavs_max_pdf=None, - intrinsic_flavors=None, - masses=HeavyQuarkMasses([1.51, 4.92, 172.5]), - masses_scheme=None, + num_flavs_max_pdf=5, + intrinsic_flavors=[], + masses=HeavyQuarkMasses( + [ + ReferenceRunning([1.51, np.inf]), + ReferenceRunning([4.92, np.inf]), + ReferenceRunning([172.5, np.inf]), + ] + ), + masses_scheme=QuarkMassScheme.POLE, matching_ratios=MatchingRatios([1.0, 1.0, 1.0]), ) return cls(heavy=heavy) From bab8cf2c44ab4ab79947b65b786f36a308424d03 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 21 Jul 2023 18:44:40 +0200 Subject: [PATCH 08/67] Fix mypy in box/{genpdf,apply} --- src/ekobox/apply.py | 46 +++++++++++++++++++++-------------- src/ekobox/genpdf/__init__.py | 6 ++--- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/ekobox/apply.py b/src/ekobox/apply.py index c392ffe78..5e62b4a06 100644 --- a/src/ekobox/apply.py +++ b/src/ekobox/apply.py @@ -1,10 +1,14 @@ """Apply operator evolution to PDF set.""" +from dataclasses import dataclass +from typing import Dict, Optional, Union + import numpy as np from eko import basis_rotation as br from eko import interpolation from eko.io import EKO +from eko.io.types import EvolutionPoint def apply_pdf( @@ -48,6 +52,14 @@ def apply_pdf( CONTRACTION = "ajbk,bk" +@dataclass +class PdfResult: + """Helper class to collect PDF results.""" + + pdfs: Dict[Union[int, str], float] + errors: Optional[Dict[Union[int, str], float]] = None + + def apply_pdf_flavor( eko: EKO, lhapdf_like, targetgrid=None, flavor_rotation=None, qed=False ): @@ -83,36 +95,33 @@ def apply_pdf_flavor( ) # build output - out_grid = {} + out_grid: Dict[EvolutionPoint, PdfResult] = {} for ep, elem in eko.items(): pdf_final = np.einsum(CONTRACTION, elem.operator, pdfs, optimize="optimal") if elem.error is not None: error_final = np.einsum(CONTRACTION, elem.error, pdfs, optimize="optimal") else: error_final = None - out_grid[ep] = { - "pdfs": dict(zip(eko.bases.targetpids, pdf_final)), - "errors": None, - } + out_grid[ep] = PdfResult(dict(zip(eko.bases.targetpids, pdf_final))) if error_final is not None: - out_grid[ep]["errors"] = dict(zip(eko.bases.targetpids, error_final)) + out_grid[ep].errors = dict(zip(eko.bases.targetpids, error_final)) # rotate to evolution basis if flavor_rotation is not None: for q2, op in out_grid.items(): pdf = flavor_rotation @ np.array( - [op["pdfs"][pid] for pid in br.flavor_basis_pids] + [op.pdfs[pid] for pid in br.flavor_basis_pids] ) if not qed: evol_basis = br.evol_basis else: evol_basis = br.unified_evol_basis - op["pdfs"] = dict(zip(evol_basis, pdf)) - if op["errors"] is not None: + op.pdfs = dict(zip(evol_basis, pdf)) + if op.errors is not None: errors = flavor_rotation @ np.array( - [op["errors"][pid] for pid in br.flavor_basis_pids] + [op.errors[pid] for pid in br.flavor_basis_pids] ) - op["errors"] = dict(zip(evol_basis, errors)) + op.errors = dict(zip(evol_basis, errors)) # rotate/interpolate to target grid if targetgrid is not None: @@ -124,11 +133,12 @@ def apply_pdf_flavor( rot = b.get_interpolation(targetgrid) for evpdf in out_grid.values(): - for pdf_label in evpdf["pdfs"]: - evpdf["pdfs"][pdf_label] = np.matmul(rot, evpdf["pdfs"][pdf_label]) - if evpdf["errors"] is not None: - evpdf["errors"][pdf_label] = np.matmul( - rot, evpdf["errors"][pdf_label] - ) - + for pdf_label in evpdf.pdfs: + evpdf.pdfs[pdf_label] = np.matmul(rot, evpdf.pdfs[pdf_label]) + if evpdf.errors is not None: + evpdf.errors[pdf_label] = np.matmul(rot, evpdf.errors[pdf_label]) + # cast back to be backward compatible + real_out_grid = {} + for ep, res in out_grid.items(): + real_out_grid[ep] = {"pdfs": res.pdfs, "errors": res.errors} return out_grid diff --git a/src/ekobox/genpdf/__init__.py b/src/ekobox/genpdf/__init__.py index af94a410e..5c88b9b7c 100644 --- a/src/ekobox/genpdf/__init__.py +++ b/src/ekobox/genpdf/__init__.py @@ -16,7 +16,7 @@ def take_data( - parent_pdf_set: Optional[Union[str, dict]] = None, + parent_pdf_set=None, members: bool = False, xgrid: Optional[List[float]] = None, evolgrid: Optional[List[EPoint]] = None, @@ -62,7 +62,7 @@ def take_data( all_blocks.append( [ generate_block( - toylh.xfxQ2, xgrid, sorted_q2grid, br.flavor_basis_pids + toylh.xfxQ2, xgrid, sorted_q2grid, list(br.flavor_basis_pids) ) ] ) @@ -86,7 +86,7 @@ def take_data( else parent_pdf_set[pid](x, Q2), xgrid, sorted_q2grid, - br.flavor_basis_pids, + list(br.flavor_basis_pids), ) ] ) From e61c8e6bf73f5ed60982a915a2ac75ed2eb26f84 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 24 Jul 2023 13:11:04 +0200 Subject: [PATCH 09/67] Fix ekomark/plots --- src/ekomark/plots.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ekomark/plots.py b/src/ekomark/plots.py index 92a155de3..90602a0c1 100644 --- a/src/ekomark/plots.py +++ b/src/ekomark/plots.py @@ -1,6 +1,7 @@ """Plotting tools to show the evolved PDF and the computed operators.""" import io import pprint +from typing import Dict, List, Tuple import matplotlib.pyplot as plt import numpy as np @@ -230,7 +231,7 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals """ ops_names = list(me.bases.targetpids) if np.allclose(ops_names, br.rotate_flavor_to_evolution): - ops_names = br.evol_basis_pids + ops_names = list(br.evol_basis_pids) else: raise ValueError("Can not reconstruct PDF names") ops_id = f"o{ops['hash'][:6]}_t{theory['hash'][:6]}" @@ -244,16 +245,16 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals # plot the operators # it's necessary to reshuffle the eko output - for mu2 in me.mu2grid: - results = me[mu2].operator - errors = me[mu2].error + for ep, op in me.items(): + results = op.operator + errors = op.error # loop on pids for label_out, res, res_err in zip(ops_names, results, errors): if label_out in skip_pdfs: continue - new_op = {} - new_op_err = {} + new_op: Dict[Tuple[int, ...], List[float]] = {} + new_op_err: Dict[Tuple[int, ...], List[float]] = {} # loop on xgrid point for j in range(len(me.xgrid)): # loop on pid in @@ -279,7 +280,7 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals fig = None try: fig = plot_operator( - f"Operator ({lab_in};{lab_out}) µ_F^2 = {mu2} GeV^2", + f"Operator ({lab_in};{lab_out}) µ_F^2 = {ep[0]} GeV^2, nf = {ep[1]}", new_op[label_in], new_op_err[label_in], ) From e40a71812bc954a5c6c90edc2b6d6e3378e8ac7e Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 24 Jul 2023 14:50:08 +0200 Subject: [PATCH 10/67] Fix ekobox/cli --- src/ekobox/cli/inspect.py | 2 +- src/ekobox/cli/run.py | 16 ++++++++-------- src/ekobox/cli/runcards.py | 4 +++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ekobox/cli/inspect.py b/src/ekobox/cli/inspect.py index f37f09cce..06f6588ed 100644 --- a/src/ekobox/cli/inspect.py +++ b/src/ekobox/cli/inspect.py @@ -27,7 +27,7 @@ def subcommand(ctx, path: pathlib.Path): @click.pass_obj def sub_mu2(operator: EKO): """Check operator's mu2grid.""" - rich.print_json(data=operator.mu2grid.tolist()) + rich.print_json(data=operator.mu2grid) @subcommand.command("cards") diff --git a/src/ekobox/cli/run.py b/src/ekobox/cli/run.py index 16e11c5fd..db88167e4 100644 --- a/src/ekobox/cli/run.py +++ b/src/ekobox/cli/run.py @@ -52,11 +52,11 @@ def subcommand(paths: Sequence[pathlib.Path]): else: output = operator.parent / OUTPUT - theory = yaml.safe_load(theory.read_text(encoding="utf-8")) - if "order" in theory: - theory = TheoryCard.from_dict(theory) - operator = yaml.safe_load(operator.read_text(encoding="utf-8")) - if "configs" in operator: - operator = OperatorCard.from_dict(operator) - - eko.solve(theory, operator, path=output) + tc = yaml.safe_load(theory.read_text(encoding="utf-8")) + if "order" in tc: + tc = TheoryCard.from_dict(tc) + oc = yaml.safe_load(operator.read_text(encoding="utf-8")) + if "configs" in oc: + oc = OperatorCard.from_dict(oc) + + eko.solve(tc, oc, path=output) diff --git a/src/ekobox/cli/runcards.py b/src/ekobox/cli/runcards.py index 1ad7d91d4..7fc46f1ef 100644 --- a/src/ekobox/cli/runcards.py +++ b/src/ekobox/cli/runcards.py @@ -2,6 +2,8 @@ import logging import pathlib +import numpy as np + from .. import cards from . import library as lib from .base import command @@ -34,6 +36,6 @@ def sub_example(destination: pathlib.Path): cards.dump(theory.raw, path=destination / "theory.yaml") operator = cards.example.operator() operator.mu0 = 1.65 - operator.mu2grid = [1e5] + operator.mugrid = [(np.sqrt(1e5), 5)] cards.dump(operator.raw, path=destination / "operator.yaml") _logger.info(f"Runcards generated to '{destination}'") From 9271ebc5950b188376c16f8bc163baea93ba8a8a Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 24 Jul 2023 15:13:25 +0200 Subject: [PATCH 11/67] Make managers class --- src/eko/evolution_operator/__init__.py | 10 +++++----- src/eko/evolution_operator/grid.py | 18 ++++++++++++++---- .../operator_matrix_element.py | 2 +- src/eko/runner/parts.py | 9 +++++---- tests/eko/evolution_operator/test_init.py | 8 +++++++- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index d079bed3d..fea8d15fe 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -623,7 +623,7 @@ def __init__( self.is_threshold = is_threshold self.op_members: OpMembers = {} self.order = tuple(config["order"]) - self.alphaem_running = self.managers["couplings"].alphaem_running + self.alphaem_running = self.managers.couplings.alphaem_running if self.log_label == "Evolution": self.a = self.compute_a() self.compute_aem_list() @@ -645,7 +645,7 @@ def xif2(self): @property def int_disp(self): """Return the interpolation dispatcher.""" - return self.managers["interpol_dispatcher"] + return self.managers.interpolator @property def grid_size(self): @@ -668,7 +668,7 @@ def mu2(self): def compute_a(self): """Return the computed values for :math:`a_s` and :math:`a_{em}`.""" - coupling = self.managers["couplings"] + coupling = self.managers.couplings a0 = coupling.a( self.mu2[0], nf_to=self.nf, @@ -708,7 +708,7 @@ def compute_aem_list(self): as1 = self.a_s[1] aem0 = self.a_em[0] aem1 = self.a_em[1] - q2ref = self.managers["couplings"].mu2_ref + q2ref = self.managers.couplings.mu2_ref delta_from = abs(self.q2_from - q2ref) delta_to = abs(self.q2_to - q2ref) # I compute the values in aem_list starting from the mu2 @@ -719,7 +719,7 @@ def compute_aem_list(self): else: a_start = np.array([as0, aem0]) mu2_start = self.q2_from - couplings = self.managers["couplings"] + couplings = self.managers.couplings mu2_steps = utils.geomspace(self.q2_from, self.q2_to, 1 + ev_op_iterations) mu2_l = mu2_steps[0] self.as_list = np.array( diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index 5035b22b2..1180697a6 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -5,6 +5,7 @@ """ import logging +from dataclasses import dataclass from typing import Any, Dict, List, Optional import numpy as np @@ -27,6 +28,15 @@ """In particular, only the ``operator`` and ``error`` fields are expected.""" +@dataclass(frozen=True) +class Managers: + """Set of steering objects.""" + + atlas: Atlas + couplings: Couplings + interpolator: InterpolatorDispatcher + + class OperatorGrid(sv.ModeMixin): """Collection of evolution operators for several scales. @@ -89,10 +99,10 @@ def __init__( self.config = config self.q2_grid = mu2grid - self.managers = dict( - thresholds_config=atlas, + self.managers = Managers( + atlas=atlas, couplings=couplings, - interpol_dispatcher=interpol_dispatcher, + interpolator=interpol_dispatcher, ) self._threshold_operators: Dict[Segment, Operator] = {} self._matching_operators: Dict[SquaredScale, OpMembers] = {} @@ -153,7 +163,7 @@ def generate(self, q2: EPoint) -> OpDict: """ # The lists of areas as produced by the thresholds - path = self.managers["thresholds_config"].path(q2) + path = self.managers.atlas.path(q2) # Prepare the path for the composition of the operator thr_ops = self.get_threshold_operators(path) # we start composing with the highest operator ... diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 809279c77..8966a62b9 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -306,7 +306,7 @@ def a_s(self): Note that here you need to use :math:`a_s^{n_f+1}` """ - sc = self.managers["couplings"] + sc = self.managers.couplings return sc.a_s( self.q2_from * (self.xif2 if self.sv_mode == sv.Modes.exponentiated else 1.0), diff --git a/src/eko/runner/parts.py b/src/eko/runner/parts.py index e385b8f49..9f97a6de5 100644 --- a/src/eko/runner/parts.py +++ b/src/eko/runner/parts.py @@ -16,13 +16,14 @@ from ..evolution_operator import matching_condition from ..evolution_operator import operator_matrix_element as ome from ..evolution_operator import physical +from ..evolution_operator.grid import Managers from ..io import EKO from ..io.items import Evolution, Matching, Operator from ..quantities.heavy_quarks import QuarkMassScheme from . import commons -def managers(eko: EKO) -> dict: +def managers(eko: EKO) -> Managers: """Collect managers for operator computation. .. todo:: @@ -32,10 +33,10 @@ def managers(eko: EKO) -> dict: """ tcard = eko.theory_card ocard = eko.operator_card - return dict( - thresholds_config=commons.atlas(tcard, ocard), + return Managers( + atlas=commons.atlas(tcard, ocard), couplings=commons.couplings(tcard, ocard), - interpol_dispatcher=commons.interpolator(ocard), + interpolator=commons.interpolator(ocard), ) diff --git a/tests/eko/evolution_operator/test_init.py b/tests/eko/evolution_operator/test_init.py index 642de5bb7..92a335f79 100644 --- a/tests/eko/evolution_operator/test_init.py +++ b/tests/eko/evolution_operator/test_init.py @@ -1,4 +1,5 @@ import os +from dataclasses import dataclass import numpy as np import pytest @@ -201,7 +202,12 @@ def compute(self, a_ref, nf, scale_from, scale_to): return a_ref -fake_managers = {"couplings": FakeCoupling()} +@dataclass(frozen=True) +class FakeManagers: + couplings: FakeCoupling + + +fake_managers = FakeManagers(couplings=FakeCoupling()) class TestOperator: From 80b85f157476f258798ec5c2d4eab2b1aec99471 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 24 Jul 2023 15:16:27 +0200 Subject: [PATCH 12/67] Use backported return in apply --- src/ekobox/apply.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ekobox/apply.py b/src/ekobox/apply.py index 5e62b4a06..ace0ccca1 100644 --- a/src/ekobox/apply.py +++ b/src/ekobox/apply.py @@ -141,4 +141,4 @@ def apply_pdf_flavor( real_out_grid = {} for ep, res in out_grid.items(): real_out_grid[ep] = {"pdfs": res.pdfs, "errors": res.errors} - return out_grid + return real_out_grid From 34c68a57a9587829a7c593563f5feaf83ecbc5fe Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 24 Jul 2023 15:28:48 +0200 Subject: [PATCH 13/67] Fix eko/io/legacy masses usage --- src/eko/io/legacy.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/eko/io/legacy.py b/src/eko/io/legacy.py index c7799d0fb..d580f7373 100644 --- a/src/eko/io/legacy.py +++ b/src/eko/io/legacy.py @@ -26,6 +26,10 @@ from .types import EvolutionPoint as EPoint from .types import RawCard, ReferenceRunning +_MC = 1.51 +_MB = 4.92 +_MT = 172.5 + def load_tar(source: os.PathLike, dest: os.PathLike, errors: bool = False): """Load tar representation from file. @@ -63,7 +67,7 @@ def load_tar(source: os.PathLike, dest: os.PathLike, errors: bool = False): if op5 is None: op5 = metaold["mu2grid"] grid = op5to4( - flavored_mugrid(op5, theory.heavy.masses, theory.heavy.matching_ratios), arrays + flavored_mugrid(op5, [_MC, _MB, _MT], theory.heavy.matching_ratios), arrays ) with EKO.create(dest) as builder: @@ -100,9 +104,9 @@ def from_old(cls, old: RawCard): intrinsic_flavors=[], masses=HeavyQuarkMasses( [ - ReferenceRunning([1.51, np.inf]), - ReferenceRunning([4.92, np.inf]), - ReferenceRunning([172.5, np.inf]), + ReferenceRunning([_MC, np.inf]), + ReferenceRunning([_MB, np.inf]), + ReferenceRunning([_MT, np.inf]), ] ), masses_scheme=QuarkMassScheme.POLE, @@ -134,7 +138,7 @@ def from_old(cls, old: RawCard): mu2list = old["mu2grid"] mu2grid = np.array(mu2list) evolgrid = flavored_mugrid( - np.sqrt(mu2grid).tolist(), [1.51, 4.92, 172.5], [1, 1, 1] + np.sqrt(mu2grid).tolist(), [_MC, _MB, _MT], [1, 1, 1] ) xgrid = XGrid(old["interpolation_xgrid"]) From d6d17340b4c2592d8a5680bbf106f93f77476961 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 24 Jul 2023 15:55:08 +0200 Subject: [PATCH 14/67] Fix remaining mypy errors --- src/eko/io/struct.py | 6 ++++-- src/eko/runner/operators.py | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index 3185c71ef..ce4679871 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -272,7 +272,7 @@ def approx( Raises ------ ValueError - if multiple values are find in the neighbourhood + if multiple values are found in the neighbourhood """ eps = np.array([ep_ for ep_ in self if ep_[1] == ep[1]]) @@ -280,7 +280,9 @@ def approx( close = eps[np.isclose(ep[0], mu2s, rtol=rtol, atol=atol)] if len(close) == 1: - return tuple(close[0]) + found = close[0] + assert isinstance(found[0], float) + return (found[0], int(found[1])) if len(close) == 0: return None raise ValueError(f"Multiple values of Q2 have been found close to {ep}") diff --git a/src/eko/runner/operators.py b/src/eko/runner/operators.py index 5a0a219c7..bfc4ce407 100644 --- a/src/eko/runner/operators.py +++ b/src/eko/runner/operators.py @@ -16,7 +16,9 @@ def retrieve( elements = [] for head in headers: inv = parts if isinstance(head, Evolution) else parts_matching - elements.append(inv[head]) + op = inv[head] + assert isinstance(op, Operator) + elements.append(op) return elements From b9cfc9e5914287b550fb75e01443197dba3b870b Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 24 Jul 2023 18:11:01 +0200 Subject: [PATCH 15/67] Change manipulate act on Operator --- src/eko/io/manipulate.py | 212 +++++++++--------------- src/ekomark/benchmark/runner.py | 13 +- src/ekomark/plots.py | 30 ++-- tests/eko/io/test_manipulate.py | 274 ++++++++++---------------------- 4 files changed, 180 insertions(+), 349 deletions(-) diff --git a/src/eko/io/manipulate.py b/src/eko/io/manipulate.py index e9cc89538..1372e9e14 100644 --- a/src/eko/io/manipulate.py +++ b/src/eko/io/manipulate.py @@ -1,7 +1,8 @@ -"""Manipulate output generate by EKO.""" +"""Manipulate operators.""" +import copy import logging import warnings -from typing import Callable, Optional, Union +from typing import Callable, Optional import numpy as np import numpy.typing as npt @@ -9,7 +10,7 @@ from .. import basis_rotation as br from .. import interpolation from ..interpolation import XGrid -from .struct import EKO, Operator +from .struct import Operator logger = logging.getLogger(__name__) @@ -18,10 +19,8 @@ SIMGRID_ROTATION = "ij,ajbk,kl->aibl" """Simultaneous grid rotation contraction indices.""" -Basis = Union[XGrid, npt.NDArray] - -def rotation(new: Optional[Basis], old: Basis, check: Callable, compute: Callable): +def rotation(new: Optional[XGrid], old: XGrid, check: Callable, compute: Callable): """Define grid rotation. This function returns the new grid to be assigned and the rotation computed, @@ -61,81 +60,66 @@ def xgrid_compute_rotation(new: XGrid, old: XGrid, interpdeg: int, swap: bool = def xgrid_reshape( - eko: EKO, + elem: Operator, + xgrid: XGrid, + interpdeg: int, targetgrid: Optional[XGrid] = None, inputgrid: Optional[XGrid] = None, -): - """Reinterpolate operators on output and/or input grids. +) -> Operator: + """Reinterpolate the operator on output and/or input grid(s). Target corresponds to the output PDF. - - The operation is in-place. - """ - eko.assert_permissions(write=True) - # calling with no arguments is an error if targetgrid is None and inputgrid is None: raise ValueError("Nor inputgrid nor targetgrid was given") - interpdeg = eko.operator_card.configs.interpolation_polynomial_degree check = xgrid_check crot = xgrid_compute_rotation # construct matrices newtarget, targetrot = rotation( targetgrid, - eko.bases.targetgrid, + xgrid, check, lambda new, old: crot(new, old, interpdeg), ) newinput, inputrot = rotation( inputgrid, - eko.bases.inputgrid, + xgrid, check, lambda new, old: crot(new, old, interpdeg, swap=True), ) - # after the checks: if there is still nothing to do, skip if targetrot is None and inputrot is None: logger.debug("Nothing done.") - return - # if no rotation is done, the grids are not modified - if targetrot is not None: - eko.bases.targetgrid = newtarget - if inputrot is not None: - eko.bases.inputgrid = newinput + return copy.deepcopy(elem) # build new grid - for ep, elem in eko.items(): - assert elem is not None - - operands = [elem.operator] - operands_errs = [elem.error] + operands = [elem.operator] + operands_errs = [elem.error] - if targetrot is not None and inputrot is None: - contraction = TARGETGRID_ROTATION - elif inputrot is not None and targetrot is None: - contraction = INPUTGRID_ROTATION - else: - contraction = SIMGRID_ROTATION + if targetrot is not None and inputrot is None: + contraction = TARGETGRID_ROTATION + elif inputrot is not None and targetrot is None: + contraction = INPUTGRID_ROTATION + else: + contraction = SIMGRID_ROTATION - if targetrot is not None: - operands.insert(0, targetrot) - operands_errs.insert(0, targetrot) - if inputrot is not None: - operands.append(inputrot) - operands_errs.append(inputrot) - - new_operator = np.einsum(contraction, *operands, optimize="optimal") - if elem.error is not None: - new_error = np.einsum(contraction, *operands_errs, optimize="optimal") - else: - new_error = None + if targetrot is not None: + operands.insert(0, targetrot) + operands_errs.insert(0, targetrot) + if inputrot is not None: + operands.append(inputrot) + operands_errs.append(inputrot) - eko[ep] = Operator(operator=new_operator, error=new_error) + new_operator = np.einsum(contraction, *operands, optimize="optimal") + if elem.error is not None: + new_error = np.einsum(contraction, *operands_errs, optimize="optimal") + else: + new_error = None - eko.update() + return Operator(operator=new_operator, error=new_error) TARGETPIDS_ROTATION = "ca,ajbk->cjbk" @@ -145,107 +129,85 @@ def xgrid_reshape( def flavor_reshape( - eko: EKO, + elem: Operator, targetpids: Optional[npt.NDArray] = None, inputpids: Optional[npt.NDArray] = None, - update: bool = True, ): - """Change the operators to have in the output targetpids and/or in the input inputpids. - - The operation is in-place. + """Change the operator to have in the output targetpids and/or in the input inputpids. Parameters ---------- - eko : + elem : the operator to be rotated targetpids : target rotation specified in the flavor basis inputpids : input rotation specified in the flavor basis - update : - update :class:`~eko.io.struct.EKO` metadata after writing """ - eko.assert_permissions(write=True) - # calling with no arguments is an error if targetpids is None and inputpids is None: raise ValueError("Nor inputpids nor targetpids was given") # now check to the current status if targetpids is not None and np.allclose( - targetpids, np.eye(len(eko.bases.targetpids)) + targetpids, np.eye(elem.operator.shape[0]) ): targetpids = None warnings.warn("The new targetpids is close to current basis") - if inputpids is not None and np.allclose( - inputpids, np.eye(len(eko.bases.inputpids)) - ): + if inputpids is not None and np.allclose(inputpids, np.eye(elem.operator.shape[2])): inputpids = None warnings.warn("The new inputpids is close to current basis") # after the checks: if there is still nothing to do, skip if targetpids is None and inputpids is None: logger.debug("Nothing done.") - return + return copy.deepcopy(elem) # flip input around if inputpids is not None: inv_inputpids = np.linalg.inv(inputpids) # build new grid - for q2, elem in eko.items(): - ops = elem.operator - errs = elem.error - if targetpids is not None and inputpids is None: - ops = np.einsum(TARGETPIDS_ROTATION, targetpids, ops, optimize="optimal") - errs = ( - np.einsum(TARGETPIDS_ROTATION, targetpids, errs, optimize="optimal") - if errs is not None - else None - ) - elif inputpids is not None and targetpids is None: - ops = np.einsum(INPUTPIDS_ROTATION, ops, inv_inputpids, optimize="optimal") - errs = ( - np.einsum(INPUTPIDS_ROTATION, errs, inv_inputpids, optimize="optimal") - if errs is not None - else None - ) - else: - ops = np.einsum( - SIMPIDS_ROTATION, targetpids, ops, inv_inputpids, optimize="optimal" - ) - errs = ( - np.einsum( - SIMPIDS_ROTATION, - targetpids, - errs, - inv_inputpids, - optimize="optimal", - ) - if errs is not None - else None + ops = elem.operator + errs = elem.error + if targetpids is not None and inputpids is None: + ops = np.einsum(TARGETPIDS_ROTATION, targetpids, ops, optimize="optimal") + errs = ( + np.einsum(TARGETPIDS_ROTATION, targetpids, errs, optimize="optimal") + if errs is not None + else None + ) + elif inputpids is not None and targetpids is None: + ops = np.einsum(INPUTPIDS_ROTATION, ops, inv_inputpids, optimize="optimal") + errs = ( + np.einsum(INPUTPIDS_ROTATION, errs, inv_inputpids, optimize="optimal") + if errs is not None + else None + ) + else: + ops = np.einsum( + SIMPIDS_ROTATION, targetpids, ops, inv_inputpids, optimize="optimal" + ) + errs = ( + np.einsum( + SIMPIDS_ROTATION, + targetpids, + errs, + inv_inputpids, + optimize="optimal", ) + if errs is not None + else None + ) - eko[q2] = Operator(operator=ops, error=errs) - - # drop PIDs - keeping them int nevertheless - # there is no meaningful way to set them in general, after rotation - if inputpids is not None: - eko.bases.inputpids = np.array([0] * len(eko.bases.inputpids)) - if targetpids is not None: - eko.bases.targetpids = np.array([0] * len(eko.bases.targetpids)) - - if update: - eko.update() + return Operator(operator=ops, error=errs) -def to_evol(eko: EKO, source: bool = True, target: bool = False): +def to_evol(elem: Operator, source: bool = True, target: bool = False): """Rotate the operator into evolution basis. - This assigns also the pids. The operation is in-place. - Parameters ---------- - eko : + elem : the operator to be rotated source : rotate on the input tensor @@ -256,27 +218,15 @@ def to_evol(eko: EKO, source: bool = True, target: bool = False): # rotate inputpids = br.rotate_flavor_to_evolution if source else None targetpids = br.rotate_flavor_to_evolution if target else None - # prevent metadata update, since flavor_reshape has not enough information - # to determine inpupids and targetpids, and they will be updated after the - # call - flavor_reshape(eko, inputpids=inputpids, targetpids=targetpids, update=False) - # assign pids - if source: - eko.bases.inputpids = inputpids - if target: - eko.bases.targetpids = targetpids - - eko.update() + return flavor_reshape(elem, inputpids=inputpids, targetpids=targetpids) -def to_uni_evol(eko: EKO, source: bool = True, target: bool = False): +def to_uni_evol(elem: Operator, source: bool = True, target: bool = False): """Rotate the operator into evolution basis. - This assigns also the pids. The operation is in-place. - Parameters ---------- - eko : + elem : the operator to be rotated source : rotate on the input tensor @@ -287,14 +237,4 @@ def to_uni_evol(eko: EKO, source: bool = True, target: bool = False): # rotate inputpids = br.rotate_flavor_to_unified_evolution if source else None targetpids = br.rotate_flavor_to_unified_evolution if target else None - # prevent metadata update, since flavor_reshape has not enough information - # to determine inpupids and targetpids, and they will be updated after the - # call - flavor_reshape(eko, inputpids=inputpids, targetpids=targetpids, update=False) - # assign pids - if source: - eko.bases.inputpids = inputpids - if target: - eko.bases.targetpids = targetpids - - eko.update() + return flavor_reshape(elem, inputpids=inputpids, targetpids=targetpids) diff --git a/src/ekomark/benchmark/runner.py b/src/ekomark/benchmark/runner.py index 8c07e7153..b1e9fc579 100644 --- a/src/ekomark/benchmark/runner.py +++ b/src/ekomark/benchmark/runner.py @@ -13,7 +13,6 @@ import eko from eko import EKO from eko import basis_rotation as br -from eko.io import manipulate from ekobox import apply from .. import pdfname @@ -116,22 +115,14 @@ def run_me(self, theory, ocard, _pdf): os.makedirs(output_path) # rotating to evolution basis if requested with EKO.edit(path) as out_copy: - change_lab = False - if self.rotate_to_evolution_basis: - qed = theory["QED"] > 0 - if not qed: - manipulate.to_evol(out_copy, source=True, target=True) - else: - manipulate.to_uni_evol(out_copy, source=True, target=True) - change_lab = True - save_operators_to_pdf( output_path, theory, ocard, out_copy, self.skip_pdfs(theory), - change_lab, + self.rotate_to_evolution_basis, + theory["QED"] > 0, ) else: # else we always rerun diff --git a/src/ekomark/plots.py b/src/ekomark/plots.py index 92a155de3..5c300f996 100644 --- a/src/ekomark/plots.py +++ b/src/ekomark/plots.py @@ -9,6 +9,7 @@ from matplotlib.colors import LogNorm from eko import basis_rotation as br +from eko.io import manipulate from eko.io.struct import EKO @@ -209,7 +210,15 @@ def plot_operator(var_name, op, op_err, log_operator=True, abs_operator=True): return fig -def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=False): +def save_operators_to_pdf( + path, + theory, + ops, + me: EKO, + skip_pdfs, + rotate_to_evolution_basis: bool, + qed: bool = False, +): """Output all operator heatmaps to PDF. Parameters @@ -228,11 +237,7 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals set whether to rename the labels """ - ops_names = list(me.bases.targetpids) - if np.allclose(ops_names, br.rotate_flavor_to_evolution): - ops_names = br.evol_basis_pids - else: - raise ValueError("Can not reconstruct PDF names") + ops_names = br.evol_basis_pids if rotate_to_evolution_basis else br.evol_basis_pids ops_id = f"o{ops['hash'][:6]}_t{theory['hash'][:6]}" path = f"{path}/{ops_id}.pdf" print(f"Plotting operators plots to {path}") @@ -244,9 +249,16 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals # plot the operators # it's necessary to reshuffle the eko output - for mu2 in me.mu2grid: - results = me[mu2].operator - errors = me[mu2].error + for mu2, op in me.items(): + change_lab = False + if rotate_to_evolution_basis: + if not qed: + op = manipulate.to_evol(op, source=True, target=True) + else: + op = manipulate.to_uni_evol(op, source=True, target=True) + change_lab = True + results = op.operator + errors = op.error # loop on pids for label_out, res, res_err in zip(ops_names, results, errors): diff --git a/tests/eko/io/test_manipulate.py b/tests/eko/io/test_manipulate.py index 3431d93ce..56ceafc0f 100644 --- a/tests/eko/io/test_manipulate.py +++ b/tests/eko/io/test_manipulate.py @@ -1,5 +1,3 @@ -import pathlib - import numpy as np import pytest @@ -21,235 +19,125 @@ def chk_keys(a, b): class TestManipulate: - def test_xgrid_reshape(self, eko_factory: EKOFactory, tmp_path: pathlib.Path): + def test_xgrid_reshape(self): # create object - muout = 10.0 - mu2out = muout**2 - epout = (mu2out, 5) + interpdeg = 1 xg = interpolation.XGrid(np.geomspace(1e-5, 1.0, 21)) - eko_factory.operator.mugrid = [(muout, 5)] - eko_factory.operator.xgrid = xg - o1 = eko_factory.get() + xgp = interpolation.XGrid(np.geomspace(1e-5, 1.0, 11)) lpids = 2 - o1[epout] = eko.io.Operator( + o1 = eko.io.Operator( operator=eko_identity([1, lpids, len(xg), lpids, len(xg)])[0] ) - xgp = interpolation.XGrid(np.geomspace(1e-5, 1.0, 11)) # only target - otpath = tmp_path / "ot.tar" - o1.deepcopy(otpath) - with EKO.edit(otpath) as ot: - manipulate.xgrid_reshape(ot, xgp) - chk_keys(o1.raw, ot.raw) - assert ot[epout].operator.shape == (lpids, len(xgp), lpids, len(xg)) - ottpath = tmp_path / "ott.tar" - o1.deepcopy(ottpath) - with EKO.edit(ottpath) as ott: - with pytest.warns(Warning): - manipulate.xgrid_reshape(ott, xg) - chk_keys(o1.raw, ott.raw) - np.testing.assert_allclose(ott[epout].operator, o1[epout].operator) + ot = manipulate.xgrid_reshape(o1, xg, interpdeg, xgp) + assert ot.operator.shape == (lpids, len(xgp), lpids, len(xg)) + ott = manipulate.xgrid_reshape(ot, xgp, interpdeg, xg) + # when blowing up again a line 0 ... 0 0 1 0 0 ... 0 becomes + # 0 ... 0 0.5 0 0.5 0 ... 0 instead + np.testing.assert_allclose( + np.sum(ott.operator, axis=3), np.sum(o1.operator, axis=3) + ) # only input - oipath = tmp_path / "oi.tar" - o1.deepcopy(oipath) - with EKO.edit(oipath) as oi: - manipulate.xgrid_reshape(oi, inputgrid=xgp) - assert oi[epout].operator.shape == (lpids, len(xg), lpids, len(xgp)) - chk_keys(o1.raw, oi.raw) - oiipath = tmp_path / "oii.tar" - o1.deepcopy(oiipath) - with EKO.edit(oiipath) as oii: - with pytest.warns(Warning): - manipulate.xgrid_reshape(oii, inputgrid=xg) - chk_keys(o1.raw, oii.raw) - np.testing.assert_allclose(oii[epout].operator, o1[epout].operator) + oi = manipulate.xgrid_reshape(o1, xg, interpdeg, inputgrid=xgp) + assert oi.operator.shape == (lpids, len(xg), lpids, len(xgp)) + oii = manipulate.xgrid_reshape(oi, xgp, interpdeg, inputgrid=xg) + np.testing.assert_allclose( + np.sum(oii.operator, axis=3), np.sum(o1.operator, axis=3) + ) + with pytest.warns(Warning): + oiii = manipulate.xgrid_reshape(oii, xg, interpdeg, inputgrid=xg) + np.testing.assert_allclose(oiii.operator, oii.operator) # both - oitpath = tmp_path / "oit.tar" - o1.deepcopy(oitpath) - with EKO.edit(oitpath) as oit: - manipulate.xgrid_reshape(oit, xgp, xgp) - chk_keys(o1.raw, oit.raw) - op = eko_identity([1, 2, len(xgp), 2, len(xgp)]) - np.testing.assert_allclose(oit[epout].operator, op[0], atol=1e-10) - + oit = manipulate.xgrid_reshape(o1, xg, interpdeg, xgp, xgp) + op = eko_identity([1, 2, len(xgp), 2, len(xgp)]) + np.testing.assert_allclose(oit.operator, op[0], atol=1e-10) # op error handling - ep2 = (25, 5) - o1[ep2] = eko.io.Operator( + o1e = eko.io.Operator( operator=eko_identity([1, lpids, len(xg), lpids, len(xg)])[0], error=0.1 * eko_identity([1, lpids, len(xg), lpids, len(xg)])[0], ) - ot2path = tmp_path / "ot2.tar" - o1.deepcopy(ot2path) - with EKO.edit(ot2path) as ot2: - manipulate.xgrid_reshape(ot2, xgp) - chk_keys(o1.raw, ot2.raw) - assert ot2[ep2].operator.shape == (lpids, len(xgp), lpids, len(xg)) - assert ot2[epout].error is None - assert ot2[ep2].error is not None + assert ot.error is None + assert oi.error is None + ot2 = manipulate.xgrid_reshape(o1e, xg, interpdeg, xgp) + assert ot2.error is not None # Python error - with pytest.raises(ValueError): - manipulate.xgrid_reshape(o1) + with pytest.raises(ValueError, match="Nor inputgrid nor targetgrid"): + manipulate.xgrid_reshape(o1, xg, interpdeg) - def test_reshape_io(self, eko_factory: EKOFactory, tmp_path): - eko_factory.path = tmp_path / "eko.tar" - eko_factory.operator.configs.interpolation_polynomial_degree = 1 - # create object - o1 = eko_factory.get() - lpids = len(o1.bases.pids) - path_copy = tmp_path / "eko_copy.tar" - o1.deepcopy(path_copy) - newxgrid = interpolation.XGrid([0.1, 1.0]) - inputpids = np.eye(lpids) - inputpids[:2, :2] = np.array([[1, -1], [1, 1]]) - with EKO.edit(path_copy) as o2: - manipulate.xgrid_reshape(o2, newxgrid, newxgrid) - manipulate.flavor_reshape(o2, inputpids=inputpids) - # reload - with EKO.read(path_copy) as o3: - chk_keys(o1.raw, o3.raw) - np.testing.assert_allclose(o3.bases.inputgrid.raw, newxgrid.raw) - np.testing.assert_allclose(o3.bases.targetgrid.raw, newxgrid.raw) - # since we use a general rotation, the inputpids are erased, - # leaving just as many zeros as PIDs, as placeholders for missing - # values - np.testing.assert_allclose(o3.bases.inputpids, [0] * len(o3.bases.pids)) - # these has to be unchanged - np.testing.assert_allclose(o3.bases.targetpids, o3.bases.pids) - - def test_flavor_reshape(self, eko_factory: EKOFactory, tmp_path: pathlib.Path): + def test_flavor_reshape(self): # create object xg = interpolation.XGrid(np.geomspace(1e-5, 1.0, 21)) - muout = 10.0 - mu2out = muout**2 - epout = (mu2out, 5) - eko_factory.operator.xgrid = xg - eko_factory.operator.mugrid = [(muout, 5)] - o1 = eko_factory.get() - lpids = len(o1.bases.pids) + lpids = len(br.flavor_basis_pids) lx = len(xg) - o1[epout] = eko.io.Operator( + o1 = eko.io.Operator( operator=eko_identity([1, lpids, lx, lpids, lx])[0], error=None, ) - # only target - target_r = np.eye(lpids) - target_r[:2, :2] = np.array([[1, -1], [1, 1]]) - tpath = tmp_path / "ot.tar" - ttpath = tmp_path / "ott.tar" - o1.deepcopy(tpath) - with EKO.edit(tpath) as ot: - manipulate.flavor_reshape(ot, target_r) - chk_keys(o1.raw, ot.raw) - assert ot[epout].operator.shape == (lpids, len(xg), lpids, len(xg)) - ot.deepcopy(ttpath) - with EKO.edit(ttpath) as ott: - manipulate.flavor_reshape(ott, np.linalg.inv(target_r)) - np.testing.assert_allclose(ott[epout].operator, o1[epout].operator) - with pytest.warns(Warning): - manipulate.flavor_reshape(ott, np.eye(lpids)) - chk_keys(o1.raw, ott.raw) - np.testing.assert_allclose(ott[epout].operator, o1[epout].operator) # only input input_r = np.eye(lpids) input_r[:2, :2] = np.array([[1, -1], [1, 1]]) - ipath = tmp_path / "oi.tar" - iipath = tmp_path / "oii.tar" - o1.deepcopy(ipath) - with EKO.edit(ipath) as oi: - manipulate.flavor_reshape(oi, inputpids=input_r) - chk_keys(o1.raw, oi.raw) - assert oi[epout].operator.shape == (lpids, len(xg), lpids, len(xg)) - oi.deepcopy(iipath) - with EKO.edit(iipath) as oii: - manipulate.flavor_reshape(oii, inputpids=np.linalg.inv(input_r)) - np.testing.assert_allclose(oii[epout].operator, o1[epout].operator) - with pytest.warns(Warning): - manipulate.flavor_reshape(oii, inputpids=np.eye(lpids)) - chk_keys(o1.raw, oii.raw) - np.testing.assert_allclose(oii[epout].operator, o1[epout].operator) + oi = manipulate.flavor_reshape(o1, inputpids=input_r) + assert oi.operator.shape == (lpids, len(xg), lpids, len(xg)) + oii = manipulate.flavor_reshape(oi, inputpids=np.linalg.inv(input_r)) + np.testing.assert_allclose(oii.operator, o1.operator) + with pytest.warns(Warning): + oiii = manipulate.flavor_reshape(oii, inputpids=np.eye(lpids)) + np.testing.assert_allclose(oiii.operator, oii.operator) + + # only target + target_r = np.eye(lpids) + target_r[:2, :2] = np.array([[1, -1], [1, 1]]) + ot = manipulate.flavor_reshape(o1, target_r) + assert ot.operator.shape == (lpids, len(xg), lpids, len(xg)) + ott = manipulate.flavor_reshape(ot, np.linalg.inv(target_r)) + np.testing.assert_allclose(ott.operator, o1.operator) + with pytest.warns(Warning): + ottt = manipulate.flavor_reshape(ott, np.eye(lpids)) + np.testing.assert_allclose(ottt.operator, ott.operator) # both - itpath = tmp_path / "oit.tar" - o1.deepcopy(itpath) - with EKO.edit(itpath) as oit: - manipulate.flavor_reshape(oit, target_r, input_r) - chk_keys(o1.raw, oit.raw) - op = eko_identity([1, lpids, len(xg), lpids, len(xg)]).copy() - np.testing.assert_allclose(oit[epout].operator, op[0], atol=1e-10) + oit = manipulate.flavor_reshape(o1, target_r, input_r) + op = eko_identity([1, lpids, len(xg), lpids, len(xg)]).copy() + np.testing.assert_allclose(oit.operator, op[0], atol=1e-10) # error - fpath = tmp_path / "fail.tar" - o1.deepcopy(fpath) - with pytest.raises(ValueError): - with EKO.edit(fpath) as of: - manipulate.flavor_reshape(of) + with pytest.raises(ValueError, match="Nor inputpids nor targetpids"): + manipulate.flavor_reshape(o1) - def test_to_evol(self, eko_factory: EKOFactory, tmp_path): + def test_to_evol(self): self._test_to_all_evol( - eko_factory, - tmp_path, manipulate.to_evol, br.rotate_flavor_to_evolution, - br.flavor_basis_pids, ) - def test_to_uni_evol(self, eko_factory: EKOFactory, tmp_path): + def test_to_uni_evol(self): self._test_to_all_evol( - eko_factory, - tmp_path, manipulate.to_uni_evol, br.rotate_flavor_to_unified_evolution, - br.flavor_basis_pids, ) - def _test_to_all_evol( - self, eko_factory: EKOFactory, tmp_path, to_evol_fnc, rot_matrix, pids - ): - xgrid = interpolation.XGrid([0.5, 1.0]) - mu_out = 2.0 - mu2_out = mu_out**2 - nfout = 4 - epout = (mu2_out, nfout) - eko_factory.operator.mu0 = float(np.sqrt(1.0)) - eko_factory.operator.mugrid = [(mu_out, nfout)] - eko_factory.operator.xgrid = xgrid - eko_factory.operator.configs.interpolation_polynomial_degree = 1 - eko_factory.operator.configs.interpolation_is_log = False - eko_factory.operator.configs.ev_op_max_order = (2, 0) - eko_factory.operator.configs.ev_op_iterations = 1 - eko_factory.operator.configs.inversion_method = runcards.InversionMethod.EXACT - o00 = eko_factory.get() - o01_path = tmp_path / "o01.tar" - o00.deepcopy(o01_path) - with EKO.edit(o01_path) as o01: - to_evol_fnc(o01) - o10_path = tmp_path / "o10.tar" - o00.deepcopy(o10_path) - with EKO.edit(o10_path) as o10: - to_evol_fnc(o10, False, True) - o11_path = tmp_path / "o11.tar" - o00.deepcopy(o11_path) - with EKO.edit(o11_path) as o11: - to_evol_fnc(o11, True, True) - chk_keys(o00.raw, o11.raw) - - with EKO.edit(o01_path) as o01: - with EKO.edit(o10_path) as o10: - with EKO.read(o11_path) as o11: - # check the input rotated one - np.testing.assert_allclose(o01.bases.inputpids, rot_matrix) - np.testing.assert_allclose(o01.bases.targetpids, pids) - # rotate also target - to_evol_fnc(o01, False, True) - np.testing.assert_allclose(o01[epout].operator, o11[epout].operator) - chk_keys(o00.raw, o01.raw) - # check the target rotated one - np.testing.assert_allclose(o10.bases.inputpids, pids) - np.testing.assert_allclose(o10.bases.targetpids, rot_matrix) - # rotate also input - to_evol_fnc(o10) - np.testing.assert_allclose(o10[epout].operator, o11[epout].operator) - chk_keys(o00.raw, o10.raw) + def _test_to_all_evol(self, to_evol_fnc, rot_matrix): + # create object + xg = interpolation.XGrid(np.geomspace(1e-5, 1.0, 21)) + lpids = len(br.flavor_basis_pids) + lx = len(xg) + o = eko.io.Operator( + operator=eko_identity([1, lpids, lx, lpids, lx])[0], + error=None, + ) + + # do it once + o01 = to_evol_fnc(o, True, False) + o10 = to_evol_fnc(o, False, True) + o11 = to_evol_fnc(o, True, True) + + # do also the other one + np.testing.assert_allclose( + to_evol_fnc(o01, False, True).operator, o11.operator, atol=1e-15 + ) + np.testing.assert_allclose( + to_evol_fnc(o10, True, False).operator, o11.operator, atol=1e-15 + ) From 6e0f434b9c1792dad9c79bed9e013e2a5b5cdd1d Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 25 Jul 2023 16:11:22 +0200 Subject: [PATCH 16/67] Remove init from benchmarks --- benchmarks/__init__.py | 0 benchmarks/ekobox/__init__.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 benchmarks/__init__.py delete mode 100644 benchmarks/ekobox/__init__.py diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/benchmarks/ekobox/__init__.py b/benchmarks/ekobox/__init__.py deleted file mode 100644 index e69de29bb..000000000 From 4699064f9e4c5e368e148f1afb9614e0e9908689 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 31 Jul 2023 11:26:54 +0200 Subject: [PATCH 17/67] Address review comments --- src/eko/io/manipulate.py | 12 ++++++------ src/ekomark/plots.py | 11 +++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/eko/io/manipulate.py b/src/eko/io/manipulate.py index 1372e9e14..72f3a641b 100644 --- a/src/eko/io/manipulate.py +++ b/src/eko/io/manipulate.py @@ -23,7 +23,7 @@ def rotation(new: Optional[XGrid], old: XGrid, check: Callable, compute: Callable): """Define grid rotation. - This function returns the new grid to be assigned and the rotation computed, + This function returns the necessary rotation, if the checks for a non-trivial new grid are passed. However, the check and the computation are delegated respectively to the @@ -31,13 +31,13 @@ def rotation(new: Optional[XGrid], old: XGrid, check: Callable, compute: Callabl """ if new is None: - return old, None + return None if check(new, old): warnings.warn("The new grid is close to the current one") - return old, None + return None - return new, compute(new, old) + return compute(new, old) def xgrid_check(new: Optional[XGrid], old: XGrid): @@ -78,13 +78,13 @@ def xgrid_reshape( crot = xgrid_compute_rotation # construct matrices - newtarget, targetrot = rotation( + targetrot = rotation( targetgrid, xgrid, check, lambda new, old: crot(new, old, interpdeg), ) - newinput, inputrot = rotation( + inputrot = rotation( inputgrid, xgrid, check, diff --git a/src/ekomark/plots.py b/src/ekomark/plots.py index 5c300f996..2e74586c6 100644 --- a/src/ekomark/plots.py +++ b/src/ekomark/plots.py @@ -233,9 +233,10 @@ def save_operators_to_pdf( DGLAP result skip_pdfs : list PDF to skip - change_lab : bool - set whether to rename the labels - + rotate_to_evolution_basis : bool + plot operators in evolution basis + qed : bool + plot operators in unified evolution basis, if the former is active """ ops_names = br.evol_basis_pids if rotate_to_evolution_basis else br.evol_basis_pids ops_id = f"o{ops['hash'][:6]}_t{theory['hash'][:6]}" @@ -250,13 +251,11 @@ def save_operators_to_pdf( # plot the operators # it's necessary to reshuffle the eko output for mu2, op in me.items(): - change_lab = False if rotate_to_evolution_basis: if not qed: op = manipulate.to_evol(op, source=True, target=True) else: op = manipulate.to_uni_evol(op, source=True, target=True) - change_lab = True results = op.operator errors = op.error @@ -283,7 +282,7 @@ def save_operators_to_pdf( continue lab_in = label_in lab_out = label_out - if change_lab: + if rotate_to_evolution_basis: index_in = br.evol_basis_pids.index(label_in) index_out = br.evol_basis_pids.index(label_out) lab_in = br.evol_basis[index_in] From 0ee166af669a0fbd50e48c4415ee4bd07cdd814d Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 31 Jul 2023 11:51:39 +0200 Subject: [PATCH 18/67] Add missing typ hints --- src/eko/io/manipulate.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/eko/io/manipulate.py b/src/eko/io/manipulate.py index 72f3a641b..c54883fdd 100644 --- a/src/eko/io/manipulate.py +++ b/src/eko/io/manipulate.py @@ -20,7 +20,9 @@ """Simultaneous grid rotation contraction indices.""" -def rotation(new: Optional[XGrid], old: XGrid, check: Callable, compute: Callable): +def rotation( + new: Optional[XGrid], old: XGrid, check: Callable, compute: Callable +) -> npt.NDArray: """Define grid rotation. This function returns the necessary rotation, @@ -40,12 +42,14 @@ def rotation(new: Optional[XGrid], old: XGrid, check: Callable, compute: Callabl return compute(new, old) -def xgrid_check(new: Optional[XGrid], old: XGrid): +def xgrid_check(new: Optional[XGrid], old: XGrid) -> bool: """Check validity of new xgrid.""" return new is not None and len(new) == len(old) and np.allclose(new.raw, old.raw) -def xgrid_compute_rotation(new: XGrid, old: XGrid, interpdeg: int, swap: bool = False): +def xgrid_compute_rotation( + new: XGrid, old: XGrid, interpdeg: int, swap: bool = False +) -> npt.NDArray: """Compute rotation from old to new xgrid. By default, the roation is computed for a target xgrid. Whether the function @@ -132,7 +136,7 @@ def flavor_reshape( elem: Operator, targetpids: Optional[npt.NDArray] = None, inputpids: Optional[npt.NDArray] = None, -): +) -> Operator: """Change the operator to have in the output targetpids and/or in the input inputpids. Parameters @@ -202,7 +206,7 @@ def flavor_reshape( return Operator(operator=ops, error=errs) -def to_evol(elem: Operator, source: bool = True, target: bool = False): +def to_evol(elem: Operator, source: bool = True, target: bool = False) -> Operator: """Rotate the operator into evolution basis. Parameters @@ -221,7 +225,7 @@ def to_evol(elem: Operator, source: bool = True, target: bool = False): return flavor_reshape(elem, inputpids=inputpids, targetpids=targetpids) -def to_uni_evol(elem: Operator, source: bool = True, target: bool = False): +def to_uni_evol(elem: Operator, source: bool = True, target: bool = False) -> Operator: """Rotate the operator into evolution basis. Parameters From 054e4b2a9c9d9b9ceeaee8aea42963aa5b5c6242 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 31 Jul 2023 12:47:10 +0200 Subject: [PATCH 19/67] Drop max_num_flavs --- benchmarks/eko/benchmark_evol_to_unity.py | 1 - benchmarks/eko/benchmark_strong_coupling.py | 63 ++++++++++--------- benchmarks/ekobox/benchmark_evol_pdf.py | 1 - doc/source/overview/tutorials/alpha_s.ipynb | 7 +-- doc/source/overview/tutorials/pdf.ipynb | 1 - extras/n3lo_bench/splitting_function_utils.py | 1 - src/eko/io/runcards.py | 1 - src/eko/quantities/couplings.py | 1 - src/ekobox/cards.py | 1 - tests/eko/kernels/test_kernels_QEDns.py | 1 - tests/eko/quantities/test_couplings.py | 2 +- tests/eko/test_couplings.py | 5 -- 12 files changed, 37 insertions(+), 48 deletions(-) diff --git a/benchmarks/eko/benchmark_evol_to_unity.py b/benchmarks/eko/benchmark_evol_to_unity.py index 41bc4b4d0..893de5de3 100644 --- a/benchmarks/eko/benchmark_evol_to_unity.py +++ b/benchmarks/eko/benchmark_evol_to_unity.py @@ -20,7 +20,6 @@ def update_cards(theory: TheoryCard, operator: OperatorCard): alphas=0.35, alphaem=0.007496, scale=float(np.sqrt(2)), - max_num_flavs=6, num_flavs_ref=None, ) theory.heavy.num_flavs_init = 4 diff --git a/benchmarks/eko/benchmark_strong_coupling.py b/benchmarks/eko/benchmark_strong_coupling.py index d13a264bd..80f65cf72 100644 --- a/benchmarks/eko/benchmark_strong_coupling.py +++ b/benchmarks/eko/benchmark_strong_coupling.py @@ -8,7 +8,7 @@ from eko.couplings import Couplings from eko.io.runcards import TheoryCard from eko.quantities.couplings import CouplingEvolutionMethod, CouplingsInfo -from eko.quantities.heavy_quarks import QuarkMassScheme +from eko.quantities.heavy_quarks import FlavorsNumber, QuarkMassScheme # try to load LHAPDF - if not available, we'll use the cached values try: @@ -35,16 +35,12 @@ use_PEGASUS = False -def ref_couplings( - ref_values, - ref_scale: float, -) -> CouplingsInfo: +def ref_couplings(ref_values, ref_scale: float, ref_nf: FlavorsNumber) -> CouplingsInfo: return CouplingsInfo( alphas=ref_values[0], alphaem=ref_values[1], scale=ref_scale, - max_num_flavs=6, - num_flavs_ref=None, + num_flavs_ref=ref_nf, ) @@ -54,11 +50,11 @@ def test_a_s(self): """Tests the value of alpha_s (for now only at LO) for a given set of parameters """ - # TODO @JCM: we need a source for this! + # source: JCM known_val = 0.0091807954 ref_mu2 = 90 ask_q2 = 125 - ref = ref_couplings([0.1181, 0.007496], np.sqrt(ref_mu2)) + ref = ref_couplings([0.1181, 0.007496], np.sqrt(ref_mu2), 5) as_FFNS_LO = Couplings( couplings=ref, order=(1, 0), @@ -80,7 +76,7 @@ def benchmark_LHA_paper(self): # LO - FFNS # note that the LO-FFNS value reported in :cite:`Giele:2002hx` # was corrected in :cite:`Dittmar:2005ed` - coupling_ref = ref_couplings([0.35, 0.007496], np.sqrt(2)) + coupling_ref = ref_couplings([0.35, 0.007496], np.sqrt(2), 4) as_FFNS_LO = Couplings( couplings=coupling_ref, order=(1, 0), @@ -141,7 +137,7 @@ def benchmark_APFEL_ffns(self): threshold_holder = matchings.Atlas.ffns(nf, 0.0) for order in [1, 2, 3]: as_FFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=threshold_holder.walls[1:-1], @@ -212,8 +208,7 @@ def benchmark_pegasus_ffns(self): } # collect my values threshold_holder = matchings.Atlas.ffns(nf, 0.0) - couplings = ref_couplings(coupling_ref, scale_ref) - couplings.max_num_flavs = 4 + couplings = ref_couplings(coupling_ref, scale_ref, nf) for order in [1, 2, 3, 4]: as_FFNS = Couplings( couplings=couplings, @@ -259,6 +254,7 @@ def benchmark_APFEL_vfns(self): Q2s = [1, 2**2, 3**2, 90**2, 100**2] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_ref = 5 threshold_list = np.power([2, 4, 175], 2) apfel_vals_dict = { 1: np.array( @@ -292,7 +288,7 @@ def benchmark_APFEL_vfns(self): # collect my values for order in [1, 2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=threshold_list, @@ -339,8 +335,9 @@ def benchmark_APFEL_vfns_fact_to_ren(self): ] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_ref = 5 fact_to_ren_lin_list = [0.567, 2.34] - threshold_list = np.power([2, 2 * 4, 2 * 92], 2) + masses_list = np.power([2, 2 * 4, 2 * 92], 2) apfel_vals_dict_list = [ { 1: np.array( @@ -437,10 +434,10 @@ def benchmark_APFEL_vfns_fact_to_ren(self): # collect my values for order in [1, 2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXACT, - masses=threshold_list.tolist(), + masses=masses_list.tolist(), hqm_scheme=QuarkMassScheme.POLE, thresholds_ratios=np.array([1.0, 1.0, 1.0]) / fact_to_ren_lin**2, ) @@ -457,7 +454,7 @@ def benchmark_APFEL_vfns_fact_to_ren(self): apfel.SetAlphaEvolution("exact") apfel.SetAlphaQCDRef(coupling_ref[0], scale_ref) apfel.SetVFNS() - apfel.SetPoleMasses(*np.sqrt(threshold_list)) + apfel.SetPoleMasses(*np.sqrt(masses_list)) apfel.SetRenFacRatio(1.0 / fact_to_ren_lin) apfel.InitializeAPFEL() # collect a_s @@ -468,12 +465,18 @@ def benchmark_APFEL_vfns_fact_to_ren(self): ) np.testing.assert_allclose(apfel_vals, np.array(apfel_vals_cur)) # check myself to APFEL - np.testing.assert_allclose(apfel_vals, np.array(my_vals), rtol=2.5e-5) + np.testing.assert_allclose( + apfel_vals, + np.array(my_vals), + rtol=2.5e-5, + err_msg=f"{order=},{fact_to_ren_lin=}", + ) def benchmark_APFEL_vfns_threshold(self): Q2s = np.power([30, 96, 150], 2) coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_ref = 4 threshold_list = np.power([30, 95, 240], 2) thresholds_ratios = [2.34**2, 1.0**2, 0.5**2] apfel_vals_dict = { @@ -487,7 +490,7 @@ def benchmark_APFEL_vfns_threshold(self): # collect my values for order in [2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=threshold_list.tolist(), @@ -496,7 +499,6 @@ def benchmark_APFEL_vfns_threshold(self): ) my_vals = [] for Q2 in Q2s: - print(Q2) my_vals.append(as_VFNS.a(Q2)[0]) # get APFEL numbers - if available else use cache apfel_vals = apfel_vals_dict[order] @@ -516,7 +518,6 @@ def benchmark_APFEL_vfns_threshold(self): apfel_vals_cur = [] for Q2 in Q2s: apfel_vals_cur.append(apfel.AlphaQCD(np.sqrt(Q2)) / (4.0 * np.pi)) - print(apfel_vals_cur) np.testing.assert_allclose(apfel_vals, np.array(apfel_vals_cur)) # check myself to APFEL np.testing.assert_allclose(apfel_vals, np.array(my_vals)) @@ -525,6 +526,7 @@ def benchmark_APFEL_vfns_msbar(self): Q2s = np.power([3, 96, 150], 2) coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_ref = 5 Q2m = np.power([2.0, 4.0, 175], 2) m2s = np.power((1.4, 4.0, 175), 2) apfel_vals_dict = { @@ -538,7 +540,7 @@ def benchmark_APFEL_vfns_msbar(self): # collect my values for order in [2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=m2s.tolist(), @@ -586,7 +588,7 @@ def benchmark_lhapdf_ffns_lo(self): # collect my values threshold_holder = matchings.Atlas.ffns(nf, 0.0) as_FFNS_LO = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(1, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_holder.walls[1:-1], @@ -629,8 +631,9 @@ def benchmark_apfel_exact(self): Q2s = [1e1, 1e2, 1e3, 1e4] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 90 + nf = 3 # collect my values - threshold_holder = matchings.Atlas.ffns(3, 0.0) + threshold_holder = matchings.Atlas.ffns(nf, 0.0) # LHAPDF cache apfel_vals_dict = { 1: np.array( @@ -660,7 +663,7 @@ def benchmark_apfel_exact(self): } for order in range(1, 3 + 1): sc = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(order, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_holder.walls[1:-1], @@ -696,8 +699,9 @@ def benchmark_lhapdf_exact(self): Q2s = [1e1, 1e2, 1e3, 1e4] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 90 + nf = 3 # collect my values - threshold_holder = matchings.Atlas.ffns(3, 0.0) + threshold_holder = matchings.Atlas.ffns(nf, 0.0) # LHAPDF cache lhapdf_vals_dict = { 1: np.array( @@ -735,7 +739,7 @@ def benchmark_lhapdf_exact(self): } for order in range(1, 4 + 1): sc = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(order, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_holder.walls[1:-1], @@ -766,6 +770,7 @@ def benchmark_lhapdf_zmvfns_lo(self): Q2s = [1, 1e1, 1e2, 1e3, 1e4] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 900 + nf_ref = 5 m2c = 2.0 m2b = 25.0 m2t = 1500.0 @@ -785,7 +790,7 @@ def benchmark_lhapdf_zmvfns_lo(self): # collect my values as_VFNS_LO = Couplings( - couplings=ref_couplings(coupling_ref, np.sqrt(scale_ref)), + couplings=ref_couplings(coupling_ref, np.sqrt(scale_ref), nf_ref), order=(1, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_list, diff --git a/benchmarks/ekobox/benchmark_evol_pdf.py b/benchmarks/ekobox/benchmark_evol_pdf.py index 3a9dc0f4a..2a9aa8ea9 100644 --- a/benchmarks/ekobox/benchmark_evol_pdf.py +++ b/benchmarks/ekobox/benchmark_evol_pdf.py @@ -23,7 +23,6 @@ def benchmark_evolve_single_member( theory.couplings.alphas = 0.118000 theory.couplings.scale = 91.1876 theory.couplings.alphaem = 0.007496 - theory.couplings.max_num_flavs = 3 theory.heavy.num_flavs_max_pdf = 3 theory.heavy.masses.c.value = 1.3 theory.heavy.masses.b.value = 4.75 diff --git a/doc/source/overview/tutorials/alpha_s.ipynb b/doc/source/overview/tutorials/alpha_s.ipynb index a9d75c0ca..d8954900d 100644 --- a/doc/source/overview/tutorials/alpha_s.ipynb +++ b/doc/source/overview/tutorials/alpha_s.ipynb @@ -40,7 +40,7 @@ "\n", "# set the (alpha_s, alpha_em) reference values\n", "couplings_ref = CouplingsInfo(\n", - " alphas=0.118, alphaem=0.007496252, scale=91.0, num_flavs_ref=None, max_num_flavs=5\n", + " alphas=0.118, alphaem=0.007496252, scale=91.0, num_flavs_ref=5\n", ")\n", "\n", "# set heavy quark masses and their threshold ratios\n", @@ -105,13 +105,10 @@ } ], "metadata": { - "interpreter": { - "hash": "0a84ba3ac8703c04e87bc503a7d00188dfd591ad56130da93c406115a1e4a408" - }, "kernelspec": { "display_name": "eko-KkPVjVhh-py3.10", "language": "python", - "name": "eko-kkpvjvhh-py3.10" + "name": "python3" }, "language_info": { "codemirror_mode": { diff --git a/doc/source/overview/tutorials/pdf.ipynb b/doc/source/overview/tutorials/pdf.ipynb index 4607ef891..9da9ead26 100644 --- a/doc/source/overview/tutorials/pdf.ipynb +++ b/doc/source/overview/tutorials/pdf.ipynb @@ -371,7 +371,6 @@ "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", "th_card.couplings.scale = 91.1876 # the reference scale at which alpha_s is provided\n", "th_card.couplings.num_flavs_ref = 5 # the number of flavors active at the alpha_s reference scale\n", - "th_card.couplings.max_num_flavs = 5 # the maximum number of flavors active in the alpha_s evolution\n", "th_card.couplings.num_flavs_init = 3 # the number of flavors active at the reference scale\n", "th_card.num_flavs_max_pdf = 5 # the maximum number of flavors active in the pdf evolution." ] diff --git a/extras/n3lo_bench/splitting_function_utils.py b/extras/n3lo_bench/splitting_function_utils.py index 6917e6bd8..db06f5c72 100644 --- a/extras/n3lo_bench/splitting_function_utils.py +++ b/extras/n3lo_bench/splitting_function_utils.py @@ -104,7 +104,6 @@ def compute_a_s(q2=None, xif2=1.0, nf=None, order=(4, 0)): alphas=0.1181, alphaem=0.007496, scale=91.00, - max_num_flavs=6, num_flavs_ref=5, ) sc = Couplings( diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index 41aef9445..6f1b585b0 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -185,7 +185,6 @@ def new_theory(self): em_running=em_running, scale=old["Qref"], num_flavs_ref=old["nfref"], - max_num_flavs=old["MaxNfAs"], ) new["heavy"] = { "num_flavs_init": nf_default(old["Q0"] ** 2.0, default_atlas(ms, ks)) diff --git a/src/eko/quantities/couplings.py b/src/eko/quantities/couplings.py index 01b11d138..f80420a9c 100644 --- a/src/eko/quantities/couplings.py +++ b/src/eko/quantities/couplings.py @@ -20,7 +20,6 @@ class CouplingsInfo(DictLike): alphas: Coupling alphaem: Coupling scale: LinearScale - max_num_flavs: FlavorsNumber num_flavs_ref: FlavorsNumber r"""Number of active flavors at strong coupling reference scale. diff --git a/src/ekobox/cards.py b/src/ekobox/cards.py index 474e7d931..e68a8ce63 100644 --- a/src/ekobox/cards.py +++ b/src/ekobox/cards.py @@ -15,7 +15,6 @@ alphaem=0.007496252, scale=91.2, num_flavs_ref=5, - max_num_flavs=6, ), heavy=dict( num_flavs_init=4, diff --git a/tests/eko/kernels/test_kernels_QEDns.py b/tests/eko/kernels/test_kernels_QEDns.py index e84956084..b85a3f013 100644 --- a/tests/eko/kernels/test_kernels_QEDns.py +++ b/tests/eko/kernels/test_kernels_QEDns.py @@ -121,7 +121,6 @@ def test_zero_true_gamma(): alphaem=alpharef[1], scale=muref, num_flavs_ref=5, - max_num_flavs=6, ) ) evmod = CouplingEvolutionMethod.EXACT diff --git a/tests/eko/quantities/test_couplings.py b/tests/eko/quantities/test_couplings.py index 00ccae9d1..83bef709c 100644 --- a/tests/eko/quantities/test_couplings.py +++ b/tests/eko/quantities/test_couplings.py @@ -3,7 +3,7 @@ def test_couplings_ref(): scale = 90.0 - d = dict(alphas=0.1, alphaem=0.01, scale=scale, max_num_flavs=6, num_flavs_ref=5) + d = dict(alphas=0.1, alphaem=0.01, scale=scale, num_flavs_ref=5) couplings = CouplingsInfo.from_dict(d) assert couplings.scale == scale assert not couplings.em_running diff --git a/tests/eko/test_couplings.py b/tests/eko/test_couplings.py index 646a56448..10535cbcb 100644 --- a/tests/eko/test_couplings.py +++ b/tests/eko/test_couplings.py @@ -55,7 +55,6 @@ def test_init(self): alphaem=alpharef[1], scale=muref, num_flavs_ref=5, - max_num_flavs=6, ) ) order = (1, 0) @@ -162,7 +161,6 @@ def test_ref(self): alphaem=alpharef[1], scale=muref, num_flavs_ref=nfref, - max_num_flavs=6, ) ) for order_s in [1, 2, 3, 4]: @@ -197,7 +195,6 @@ def test_ref_copy_e841b0dfdee2f31d9ccc1ecee4d9d1a6f6624313(self): alphaem=alpharef[1], scale=muref, num_flavs_ref=3, # reference nf is needed to force the matching - max_num_flavs=6, ) ) sc = Couplings( @@ -238,7 +235,6 @@ def test_exact(self): alphaem=alpharef[1], scale=muref, num_flavs_ref=nfref, - max_num_flavs=6, em_running=em_running, ) ) @@ -301,7 +297,6 @@ def benchmark_expanded_n3lo(self): alphaem=alpharef[1], scale=muref, num_flavs_ref=5, - max_num_flavs=6, ) m2c = 2 m2b = 25 From cfc7ee53bd807c5377263fd1024e313d4d5f8315 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 31 Jul 2023 12:58:29 +0200 Subject: [PATCH 20/67] Drop num_flavs_max_pdf --- benchmarks/ekobox/benchmark_evol_pdf.py | 1 - doc/source/overview/tutorials/pdf.ipynb | 3 +-- src/eko/io/legacy.py | 1 - src/eko/io/runcards.py | 1 - src/eko/quantities/heavy_quarks.py | 2 -- src/ekobox/cards.py | 1 - tests/eko/test_quantities.py | 1 - 7 files changed, 1 insertion(+), 9 deletions(-) diff --git a/benchmarks/ekobox/benchmark_evol_pdf.py b/benchmarks/ekobox/benchmark_evol_pdf.py index 2a9aa8ea9..c85083604 100644 --- a/benchmarks/ekobox/benchmark_evol_pdf.py +++ b/benchmarks/ekobox/benchmark_evol_pdf.py @@ -23,7 +23,6 @@ def benchmark_evolve_single_member( theory.couplings.alphas = 0.118000 theory.couplings.scale = 91.1876 theory.couplings.alphaem = 0.007496 - theory.heavy.num_flavs_max_pdf = 3 theory.heavy.masses.c.value = 1.3 theory.heavy.masses.b.value = 4.75 theory.heavy.masses.t.value = 172 diff --git a/doc/source/overview/tutorials/pdf.ipynb b/doc/source/overview/tutorials/pdf.ipynb index 9da9ead26..0719d9d63 100644 --- a/doc/source/overview/tutorials/pdf.ipynb +++ b/doc/source/overview/tutorials/pdf.ipynb @@ -371,8 +371,7 @@ "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", "th_card.couplings.scale = 91.1876 # the reference scale at which alpha_s is provided\n", "th_card.couplings.num_flavs_ref = 5 # the number of flavors active at the alpha_s reference scale\n", - "th_card.couplings.num_flavs_init = 3 # the number of flavors active at the reference scale\n", - "th_card.num_flavs_max_pdf = 5 # the maximum number of flavors active in the pdf evolution." + "th_card.heavy.num_flavs_init = 3 # the number of flavors active at the reference scale" ] }, { diff --git a/src/eko/io/legacy.py b/src/eko/io/legacy.py index d580f7373..cb7b24644 100644 --- a/src/eko/io/legacy.py +++ b/src/eko/io/legacy.py @@ -100,7 +100,6 @@ def from_old(cls, old: RawCard): """Load from old metadata.""" heavy = HeavyInfo( num_flavs_init=4, - num_flavs_max_pdf=5, intrinsic_flavors=[], masses=HeavyQuarkMasses( [ diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index 6f1b585b0..c66e48dc4 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -190,7 +190,6 @@ def new_theory(self): "num_flavs_init": nf_default(old["Q0"] ** 2.0, default_atlas(ms, ks)) if old["nf0"] is None else old["nf0"], - "num_flavs_max_pdf": old["MaxNfPdf"], "matching_ratios": self.heavies("k%sThr", old), "masses_scheme": old["HQ"], } diff --git a/src/eko/quantities/heavy_quarks.py b/src/eko/quantities/heavy_quarks.py index df0285649..ab0ece64a 100644 --- a/src/eko/quantities/heavy_quarks.py +++ b/src/eko/quantities/heavy_quarks.py @@ -96,8 +96,6 @@ class HeavyInfo(DictLike): I.e. :math:`n_{f,\text{ref}}(\mu^2_0)`, formerly called ``nf0``. """ - num_flavs_max_pdf: FlavorsNumber - """Maximum number of quark PDFs.""" intrinsic_flavors: IntrinsicFlavors """List of intrinsic quark PDFs.""" masses: HeavyQuarkMasses diff --git a/src/ekobox/cards.py b/src/ekobox/cards.py index e68a8ce63..a69b32ad6 100644 --- a/src/ekobox/cards.py +++ b/src/ekobox/cards.py @@ -18,7 +18,6 @@ ), heavy=dict( num_flavs_init=4, - num_flavs_max_pdf=6, intrinsic_flavors=[4], masses=[ReferenceRunning([mq, nan]) for mq in (2.0, 4.5, 173.07)], masses_scheme="POLE", diff --git a/tests/eko/test_quantities.py b/tests/eko/test_quantities.py index 0c2628b30..8fd6c298f 100644 --- a/tests/eko/test_quantities.py +++ b/tests/eko/test_quantities.py @@ -34,7 +34,6 @@ def test_HeavyQuarks(): def test_HeavyInfo(): i = hq.HeavyInfo( num_flavs_init=4, - num_flavs_max_pdf=6, intrinsic_flavors=[4, 5], masses=hq.HeavyQuarkMasses( [ From 8b3899d02dd80e6ea4dc31a0c517ac7785bcc3d8 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 31 Jul 2023 19:13:24 +0200 Subject: [PATCH 21/67] Start dropping intrinsic --- benchmarks/eko/benchmark_evol_to_unity.py | 1 - src/eko/evolution_operator/grid.py | 8 +- .../evolution_operator/matching_condition.py | 48 +++++----- .../operator_matrix_element.py | 8 +- src/eko/evolution_operator/physical.py | 23 ++--- src/eko/io/legacy.py | 1 - src/eko/io/runcards.py | 5 - src/eko/io/types.py | 1 - src/eko/quantities/heavy_quarks.py | 10 +- src/eko/runner/legacy.py | 2 - src/eko/runner/managed.py | 2 - src/eko/runner/parts.py | 40 ++------ src/ekobox/cards.py | 1 - .../test_matching_condition.py | 91 +++++-------------- tests/eko/evolution_operator/test_physical.py | 36 +++----- tests/eko/io/test_runcards.py | 1 - tests/eko/test_quantities.py | 1 - 17 files changed, 80 insertions(+), 199 deletions(-) diff --git a/benchmarks/eko/benchmark_evol_to_unity.py b/benchmarks/eko/benchmark_evol_to_unity.py index 893de5de3..d269db202 100644 --- a/benchmarks/eko/benchmark_evol_to_unity.py +++ b/benchmarks/eko/benchmark_evol_to_unity.py @@ -23,7 +23,6 @@ def update_cards(theory: TheoryCard, operator: OperatorCard): num_flavs_ref=None, ) theory.heavy.num_flavs_init = 4 - theory.heavy.intrinsic_flavors = [4, 5] theory.heavy.masses.c.value = 1.0 theory.heavy.masses.b.value = 4.75 theory.heavy.masses.t.value = 173.0 diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index 1180697a6..382ece751 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -60,7 +60,6 @@ def __init__( masses: List[float], mass_scheme, thresholds_ratios: List[float], - intrinsic_flavors: list, xif: float, n3lo_ad_variation: tuple, configs: Configs, @@ -72,7 +71,6 @@ def __init__( # check config: Dict[str, Any] = {} config["order"] = order - config["intrinsic_range"] = intrinsic_flavors config["xif2"] = xif**2 config["HQ"] = mass_scheme config["ModSV"] = configs.scvar_method @@ -171,16 +169,15 @@ def generate(self, q2: EPoint) -> OpDict: operator.compute() is_downward = is_downward_path(path) - intrinsic_range = [4, 5, 6] if is_downward else self.config["intrinsic_range"] qed = self.config["order"][1] > 0 final_op = physical.PhysicalOperator.ad_to_evol_map( - operator.op_members, operator.nf, operator.q2_to, intrinsic_range, qed + operator.op_members, operator.nf, operator.q2_to, qed ) # and multiply the lower ones from the right for op in reversed(list(thr_ops)): phys_op = physical.PhysicalOperator.ad_to_evol_map( - op.op_members, op.nf, op.q2_to, intrinsic_range, qed + op.op_members, op.nf, op.q2_to, qed ) # join with the basis rotation, since matching requires c+ (or likewise) @@ -189,7 +186,6 @@ def generate(self, q2: EPoint) -> OpDict: self._matching_operators[op.q2_to], nf_match, op.q2_to, - intrinsic_range=intrinsic_range, qed=qed, ) if is_downward: diff --git a/src/eko/evolution_operator/matching_condition.py b/src/eko/evolution_operator/matching_condition.py index 059617fbf..e84ef4d2e 100644 --- a/src/eko/evolution_operator/matching_condition.py +++ b/src/eko/evolution_operator/matching_condition.py @@ -20,7 +20,6 @@ def split_ad_to_evol_map( op_members, nf, q2_thr, - intrinsic_range, qed=False, ): """ @@ -35,8 +34,6 @@ def split_ad_to_evol_map( number of active flavors *below* the threshold q2_thr: float threshold value - intrinsic_range : list - list of intrinsic quark pids qed : bool activate qed """ @@ -78,27 +75,26 @@ def split_ad_to_evol_map( ) # intrinsic matching - if len(intrinsic_range) != 0: - op_id = member.OpMember.id_like(op_members[(200, 200)]) - for intr_fl in intrinsic_range: - ihq = br.quark_names[intr_fl - 1] # find name - if intr_fl > nf + 1: - # keep the higher quarks as they are - m[f"{ihq}+.{ihq}+"] = op_id.copy() - m[f"{ihq}-.{ihq}-"] = op_id.copy() - elif intr_fl == nf + 1: - # match the missing contribution from h+ and h- - m.update( - { - f"{ihq}+.{ihq}+": op_members[ - (br.matching_hplus_pid, br.matching_hplus_pid) - ], - f"S.{ihq}+": op_members[(100, br.matching_hplus_pid)], - f"g.{ihq}+": op_members[(21, br.matching_hplus_pid)], - f"{ihq}-.{ihq}-": op_members[ - (br.matching_hminus_pid, br.matching_hminus_pid) - ], - # f"V.{ihq}-": op_members[(200, br.matching_hminus_pid)], - } - ) + op_id = member.OpMember.id_like(op_members[(200, 200)]) + for intr_fl in [4, 5, 6]: + ihq = br.quark_names[intr_fl - 1] # find name + if intr_fl > nf + 1: + # keep the higher quarks as they are + m[f"{ihq}+.{ihq}+"] = op_id.copy() + m[f"{ihq}-.{ihq}-"] = op_id.copy() + elif intr_fl == nf + 1: + # match the missing contribution from h+ and h- + m.update( + { + f"{ihq}+.{ihq}+": op_members[ + (br.matching_hplus_pid, br.matching_hplus_pid) + ], + f"S.{ihq}+": op_members[(100, br.matching_hplus_pid)], + f"g.{ihq}+": op_members[(21, br.matching_hplus_pid)], + f"{ihq}-.{ihq}-": op_members[ + (br.matching_hminus_pid, br.matching_hminus_pid) + ], + # f"V.{ihq}-": op_members[(200, br.matching_hminus_pid)], + } + ) return cls.promote_names(m, q2_thr) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 8966a62b9..b45e06c81 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -214,10 +214,6 @@ class OperatorMatrixElement(Operator): def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): super().__init__(config, managers, Segment(q2, q2, nf)) self.backward_method = config["backward_inversion"] if is_backward else None - if is_backward: - self.is_intrinsic = True - else: - self.is_intrinsic = bool(len(config["intrinsic_range"]) != 0) self.L = L self.is_msbar = is_msbar # Note for the moment only QCD matching is implemented @@ -238,7 +234,7 @@ def labels(self): logger.warning("%s: skipping non-singlet sector", self.log_label) else: labels.append((200, 200)) - if self.is_intrinsic or self.backward_method is not None: + if self.backward_method is not None: # intrinsic labels, which are not zero at NLO labels.append((br.matching_hminus_pid, br.matching_hminus_pid)) # These contributions are always 0 for the moment @@ -254,7 +250,7 @@ def labels(self): (br.matching_hplus_pid, 100), ] ) - if self.is_intrinsic or self.backward_method is not None: + if self.backward_method is not None: labels.extend( [ (21, br.matching_hplus_pid), diff --git a/src/eko/evolution_operator/physical.py b/src/eko/evolution_operator/physical.py index c963e2a26..6a5138d25 100644 --- a/src/eko/evolution_operator/physical.py +++ b/src/eko/evolution_operator/physical.py @@ -22,7 +22,7 @@ class PhysicalOperator(member.OperatorBase): """ @classmethod - def ad_to_evol_map(cls, op_members, nf, q2_final, intrinsic_range, qed=False): + def ad_to_evol_map(cls, op_members, nf, q2_final, qed=False): """ Obtain map between the 3-dimensional anomalous dimension basis and the 4-dimensional evolution basis. @@ -34,8 +34,6 @@ def ad_to_evol_map(cls, op_members, nf, q2_final, intrinsic_range, qed=False): operator members in anomalous dimension basis nf : int number of active light flavors - intrinsic_range : sequence - intrinsic heavy flavors qed : bool activate qed @@ -93,15 +91,14 @@ def ad_to_evol_map(cls, op_members, nf, q2_final, intrinsic_range, qed=False): m["Tu8.Tu8"] = op_members[(br.non_singlet_pids_map["ns+u"], 0)] m["Vu8.Vu8"] = op_members[(br.non_singlet_pids_map["ns-u"], 0)] # deal with intrinsic heavy quark PDFs - if intrinsic_range is not None: - hqfl = "cbt" - op_id = member.OpMember.id_like(op_members[(21, 21)]) - for intr_fl in intrinsic_range: - if intr_fl <= nf: # light quarks are not intrinsic - continue - hq = hqfl[intr_fl - 4] # find name - # intrinsic means no evolution, i.e. they are evolving with the identity - m[f"{hq}+.{hq}+"] = op_id.copy() - m[f"{hq}-.{hq}-"] = op_id.copy() + hqfl = "cbt" + op_id = member.OpMember.id_like(op_members[(21, 21)]) + for intr_fl in [4, 5, 6]: + if intr_fl <= nf: # light quarks are not intrinsic + continue + hq = hqfl[intr_fl - 4] # find name + # intrinsic means no evolution, i.e. they are evolving with the identity + m[f"{hq}+.{hq}+"] = op_id.copy() + m[f"{hq}-.{hq}-"] = op_id.copy() # map key to MemberName return cls.promote_names(m, q2_final) diff --git a/src/eko/io/legacy.py b/src/eko/io/legacy.py index cb7b24644..8491a6acc 100644 --- a/src/eko/io/legacy.py +++ b/src/eko/io/legacy.py @@ -100,7 +100,6 @@ def from_old(cls, old: RawCard): """Load from old metadata.""" heavy = HeavyInfo( num_flavs_init=4, - intrinsic_flavors=[], masses=HeavyQuarkMasses( [ ReferenceRunning([_MC, np.inf]), diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index c66e48dc4..d5c8c36e8 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -193,11 +193,6 @@ def new_theory(self): "matching_ratios": self.heavies("k%sThr", old), "masses_scheme": old["HQ"], } - intrinsic = [] - for idx, q in enumerate(hq.FLAVORS): - if old.get(f"i{q}".upper()) == 1: - intrinsic.append(idx + 4) - new["heavy"]["intrinsic_flavors"] = intrinsic if old["HQ"] == "POLE": new["heavy"]["masses"] = [[m, nan] for m in ms] elif old["HQ"] == "MSBAR": diff --git a/src/eko/io/types.py b/src/eko/io/types.py index 5573bafbb..b92628116 100644 --- a/src/eko/io/types.py +++ b/src/eko/io/types.py @@ -22,7 +22,6 @@ Order = Tuple[int, int] FlavorsNumber = int FlavorIndex = int -IntrinsicFlavors = typing.List[FlavorIndex] N3LOAdVariation = typing.Tuple[int, int, int, int] # Evolution coordinates diff --git a/src/eko/quantities/heavy_quarks.py b/src/eko/quantities/heavy_quarks.py index ab0ece64a..3b081a03d 100644 --- a/src/eko/quantities/heavy_quarks.py +++ b/src/eko/quantities/heavy_quarks.py @@ -6,13 +6,7 @@ import numpy as np from ..io.dictlike import DictLike -from ..io.types import ( - FlavorsNumber, - IntrinsicFlavors, - LinearScale, - ReferenceRunning, - SquaredScale, -) +from ..io.types import FlavorsNumber, LinearScale, ReferenceRunning, SquaredScale FLAVORS = "cbt" @@ -96,8 +90,6 @@ class HeavyInfo(DictLike): I.e. :math:`n_{f,\text{ref}}(\mu^2_0)`, formerly called ``nf0``. """ - intrinsic_flavors: IntrinsicFlavors - """List of intrinsic quark PDFs.""" masses: HeavyQuarkMasses """List of heavy quark masses.""" masses_scheme: QuarkMassScheme diff --git a/src/eko/runner/legacy.py b/src/eko/runner/legacy.py index c964c3415..76d6f1a8a 100644 --- a/src/eko/runner/legacy.py +++ b/src/eko/runner/legacy.py @@ -44,7 +44,6 @@ def __init__( """ new_theory, new_operator = runcards.update(theory_card, operators_card) - new_theory.heavy.intrinsic_flavors = [4, 5, 6] # Store inputs self.path = path @@ -69,7 +68,6 @@ def __init__( masses=masses, mass_scheme=new_theory.heavy.masses_scheme.value, thresholds_ratios=new_theory.heavy.squared_ratios, - intrinsic_flavors=new_theory.heavy.intrinsic_flavors, xif=new_theory.xif, configs=new_operator.configs, debug=new_operator.debug, diff --git a/src/eko/runner/managed.py b/src/eko/runner/managed.py index c353decde..dc253e2ea 100644 --- a/src/eko/runner/managed.py +++ b/src/eko/runner/managed.py @@ -20,8 +20,6 @@ def solve(theory: TheoryCard, operator: OperatorCard, path: Path): """Solve DGLAP equations in terms of evolution kernel operators (EKO).""" - theory.heavy.intrinsic_flavors = [4, 5, 6] - with EKO.create(path) as builder: eko = builder.load_cards(theory, operator).build() # pylint: disable=E1101 diff --git a/src/eko/runner/parts.py b/src/eko/runner/parts.py index 9f97a6de5..22a2ff9ca 100644 --- a/src/eko/runner/parts.py +++ b/src/eko/runner/parts.py @@ -40,32 +40,6 @@ def managers(eko: EKO) -> Managers: ) -def blowup_info(eko: EKO) -> dict: - """Prepare common information to blow up to flavor basis. - - Note - ---- - ``intrinsic_range`` is a fully deprecated feature, here and anywhere else, - since a full range is already always used for backward evolution, and it is - not harmful to use it also for forward. - - Indeed, the only feature of non-intrinsic evolution is to absorb a - non-trivial boundary condition when an intrinsic PDF is defined. - But to achieve this, is sufficient to not specify any intrinsic boundary - condition at all, while if something is there, it is intuitive enough that - it will be consistently evolved. - - Moreover, since two different behavior are applied for the forward and - backward evolution, the intrinsic range is a "non-local" function, since it - does not depend only on the evolution segment, but also on the previous - evolution history (to determine if evolution is backward in flavor, - irrespectively of happening for an increasing or decreasing interval in - scale at fixed flavor). - - """ - return dict(intrinsic_range=[4, 5, 6], qed=eko.theory_card.order[1] > 0) - - def evolve_configs(eko: EKO) -> dict: """Create configs for :class:`Operator`. @@ -99,10 +73,10 @@ def evolve(eko: EKO, recipe: Evolution) -> Operator: ) op.compute() - binfo = blowup_info(eko) + qed = eko.theory_card.order[1] > 0 res, err = physical.PhysicalOperator.ad_to_evol_map( - op.op_members, op.nf, op.q2_to, **binfo - ).to_flavor_basis_tensor(qed=binfo["qed"]) + op.op_members, op.nf, op.q2_to, qed + ).to_flavor_basis_tensor(qed) return Operator(res, err) @@ -120,7 +94,6 @@ def matching_configs(eko: EKO) -> dict: return dict( **evolve_configs(eko), backward_inversion=ocard.configs.inversion_method, - intrinsic_range=tcard.heavy.intrinsic_flavors, ) @@ -148,11 +121,10 @@ def match(eko: EKO, recipe: Matching) -> Operator: eko.theory_card.heavy.masses_scheme is QuarkMassScheme.MSBAR, ) op.compute() - - binfo = blowup_info(eko) + qed = eko.theory_card.order[1] > 0 nf_match = op.nf - 1 if recipe.inverse else op.nf res, err = matching_condition.MatchingCondition.split_ad_to_evol_map( - op.op_members, nf_match, recipe.scale, **binfo - ).to_flavor_basis_tensor(qed=binfo["qed"]) + op.op_members, nf_match, recipe.scale, qed + ).to_flavor_basis_tensor(qed) return Operator(res, err) diff --git a/src/ekobox/cards.py b/src/ekobox/cards.py index a69b32ad6..482e65faf 100644 --- a/src/ekobox/cards.py +++ b/src/ekobox/cards.py @@ -18,7 +18,6 @@ ), heavy=dict( num_flavs_init=4, - intrinsic_flavors=[4], masses=[ReferenceRunning([mq, nan]) for mq in (2.0, 4.5, 173.07)], masses_scheme="POLE", matching_ratios=[1.0, 1.0, 1.0], diff --git a/tests/eko/evolution_operator/test_matching_condition.py b/tests/eko/evolution_operator/test_matching_condition.py index 8cbd6b537..bb6aeebbc 100644 --- a/tests/eko/evolution_operator/test_matching_condition.py +++ b/tests/eko/evolution_operator/test_matching_condition.py @@ -22,12 +22,6 @@ def mkOME(self): (br.matching_hplus_pid, 21), (200, 200), (br.matching_hminus_pid, 200), - ]: - ome.update({key: mkOM(self.shape)}) - return ome - - def update_intrinsic_OME(self, ome): - for key in [ (br.matching_hplus_pid, br.matching_hplus_pid), (br.matching_hminus_pid, br.matching_hminus_pid), (200, br.matching_hminus_pid), @@ -35,10 +29,11 @@ def update_intrinsic_OME(self, ome): (21, br.matching_hplus_pid), ]: ome.update({key: mkOM(self.shape)}) + return ome def test_split_ad_to_evol_map(self): ome = self.mkOME() - a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, []) + a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1) triv_keys = [ "V.V", "T3.T3", @@ -55,6 +50,14 @@ def test_split_ad_to_evol_map(self): "c+.S", "c+.g", # "c-.V", + "S.c+", + "g.c+", + "c+.c+", + "c-.c-", + "b+.b+", + "b-.b-", + "t+.t+", + "t-.t-", ] assert sorted(str(k) for k in a.op_members.keys()) == sorted( [*triv_keys, *keys3] @@ -63,36 +66,8 @@ def test_split_ad_to_evol_map(self): a.op_members[member.MemberName("V.V")].value, ome[(200, 200)].value, ) - # # if alpha is zero, nothing non-trivial should happen - b = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, []) - assert sorted(str(k) for k in b.op_members.keys()) == sorted( - [*triv_keys, *keys3] - ) - # assert_almost_equal( - # b.op_members[member.MemberName("V.V")].value, - # np.eye(self.shape[0]), - # ) - # nf=3 + IC - self.update_intrinsic_OME(ome) - c = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [4]) - assert sorted(str(k) for k in c.op_members.keys()) == sorted( - [*triv_keys, *keys3, "S.c+", "g.c+", "c+.c+", "c-.c-"] - ) - assert_almost_equal( - c.op_members[member.MemberName("V.V")].value, - b.op_members[member.MemberName("V.V")].value, - ) - # nf=3 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [5]) - assert sorted(str(k) for k in d.op_members.keys()) == sorted( - [*triv_keys, *keys3, "b+.b+", "b-.b-"] - ) - assert_almost_equal( - d.op_members[member.MemberName("b+.b+")].value, - np.eye(self.shape[0]), - ) # nf=4 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1, [5]) + d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1) assert sorted(str(k) for k in d.op_members.keys()) == sorted( [ *triv_keys, @@ -106,6 +81,8 @@ def test_split_ad_to_evol_map(self): "b+.b+", # "b-.V", "b-.b-", + "t+.t+", + "t-.t-", ] ) assert_almost_equal( @@ -127,7 +104,7 @@ def test_split_ad_to_evol_map(self): def test_split_ad_to_evol_map_qed(self): ome = self.mkOME() - a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [], qed=True) + a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, qed=True) triv_keys = [ "ph.ph", "S.S", @@ -144,7 +121,15 @@ def test_split_ad_to_evol_map_qed(self): keys3 = [ "c+.S", "c+.g", + "S.c+", + "g.c+", + "c+.c+", + "c-.c-", # "c-.V", + "b+.b+", + "b-.b-", + "t+.t+", + "t-.t-", ] assert sorted(str(k) for k in a.op_members.keys()) == sorted( [*triv_keys, *keys3] @@ -153,36 +138,8 @@ def test_split_ad_to_evol_map_qed(self): a.op_members[member.MemberName("V.V")].value, ome[(200, 200)].value, ) - # # if alpha is zero, nothing non-trivial should happen - b = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [], qed=True) - assert sorted(str(k) for k in b.op_members.keys()) == sorted( - [*triv_keys, *keys3] - ) - # assert_almost_equal( - # b.op_members[member.MemberName("V.V")].value, - # np.eye(self.shape[0]), - # ) - # nf=3 + IC - self.update_intrinsic_OME(ome) - c = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [4], qed=True) - assert sorted(str(k) for k in c.op_members.keys()) == sorted( - [*triv_keys, *keys3, "S.c+", "g.c+", "c+.c+", "c-.c-"] - ) - assert_almost_equal( - c.op_members[member.MemberName("V.V")].value, - b.op_members[member.MemberName("V.V")].value, - ) - # nf=3 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [5], qed=True) - assert sorted(str(k) for k in d.op_members.keys()) == sorted( - [*triv_keys, *keys3, "b+.b+", "b-.b-"] - ) - assert_almost_equal( - d.op_members[member.MemberName("b+.b+")].value, - np.eye(self.shape[0]), - ) # nf=4 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1, [5], qed=True) + d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1, qed=True) assert sorted(str(k) for k in d.op_members.keys()) == sorted( [ *triv_keys, @@ -196,6 +153,8 @@ def test_split_ad_to_evol_map_qed(self): "b+.b+", # "b-.V", "b-.b-", + "t+.t+", + "t-.t-", ] ) assert_almost_equal( diff --git a/tests/eko/evolution_operator/test_physical.py b/tests/eko/evolution_operator/test_physical.py index b4a9936b6..fb74fb617 100644 --- a/tests/eko/evolution_operator/test_physical.py +++ b/tests/eko/evolution_operator/test_physical.py @@ -221,27 +221,21 @@ def mk_op_members(shape=(2, 2), qed=False): return om -def get_ad_to_evol_map(nf, intrinsic_range=None, qed=False): +def get_ad_to_evol_map(nf, qed=False): oms = mk_op_members(qed=qed) - m = PhysicalOperator.ad_to_evol_map(oms, nf, 1, intrinsic_range, qed) + m = PhysicalOperator.ad_to_evol_map(oms, nf, 1, qed) return sorted(map(str, m.op_members.keys())) def test_ad_to_evol_map(): triv_ops = ("S.S", "S.g", "g.S", "g.g", "V.V", "V3.V3", "T3.T3", "V8.V8", "T8.T8") # nf=3 - assert sorted(triv_ops) == get_ad_to_evol_map(3) - # nf=3 + IC - assert sorted([*triv_ops, "c+.c+", "c-.c-"]) == get_ad_to_evol_map(3, [4]) - # nf=3 + IC + IB assert sorted( - [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-"] - ) == get_ad_to_evol_map(3, [4, 5]) - # nf=4 + IC(non-existant) + IB - ks = sorted([*triv_ops, "V15.V15", "T15.T15", "b+.b+", "b-.b-"]) - assert ks == get_ad_to_evol_map(4, [4, 5]) - # nf=4 + IB - assert ks == get_ad_to_evol_map(4, [5]) + [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-", "t+.t+", "t-.t-"] + ) == get_ad_to_evol_map(3) + # nf=4 + ks = sorted([*triv_ops, "V15.V15", "T15.T15", "b+.b+", "b-.b-", "t+.t+", "t-.t-"]) + assert ks == get_ad_to_evol_map(4) # nf=6 assert sorted( [*triv_ops, "T15.T15", "V15.V15", "T24.T24", "V24.V24", "T35.T35", "V35.V35"] @@ -274,18 +268,12 @@ def test_ad_to_evol_map_qed(): "Td3.Td3", ) # nf=3 - assert sorted(triv_ops) == get_ad_to_evol_map(3, qed=True) - # nf=3 + IC - assert sorted([*triv_ops, "c+.c+", "c-.c-"]) == get_ad_to_evol_map(3, [4], qed=True) - # nf=3 + IC + IB assert sorted( - [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-"] - ) == get_ad_to_evol_map(3, [4, 5], qed=True) - # nf=4 + IC(non-existant) + IB - ks = sorted([*triv_ops, "Vu3.Vu3", "Tu3.Tu3", "b+.b+", "b-.b-"]) - assert ks == get_ad_to_evol_map(4, [4, 5], qed=True) - # nf=4 + IB - assert ks == get_ad_to_evol_map(4, [5], qed=True) + [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-", "t+.t+", "t-.t-"] + ) == get_ad_to_evol_map(3, True) + # nf=4 + ks = sorted([*triv_ops, "Vu3.Vu3", "Tu3.Tu3", "b+.b+", "b-.b-", "t+.t+", "t-.t-"]) + assert ks == get_ad_to_evol_map(4, True) # nf=6 assert sorted( [*triv_ops, "Tu3.Tu3", "Vu3.Vu3", "Td8.Td8", "Vd8.Vd8", "Tu8.Tu8", "Vu8.Vu8"] diff --git a/tests/eko/io/test_runcards.py b/tests/eko/io/test_runcards.py index 6af37edcb..0a391047b 100644 --- a/tests/eko/io/test_runcards.py +++ b/tests/eko/io/test_runcards.py @@ -100,7 +100,6 @@ def test_runcards_quarkmass(): tc["IC"] = 1 oc = copy.deepcopy(operator_card) nt, no = rc.update(tc, oc) - assert nt.heavy.intrinsic_flavors == [4] for _, scale in nt.heavy.masses: assert np.isnan(scale) m2s = rc.masses(nt, no.configs.evolution_method) diff --git a/tests/eko/test_quantities.py b/tests/eko/test_quantities.py index 8fd6c298f..f9dcb9203 100644 --- a/tests/eko/test_quantities.py +++ b/tests/eko/test_quantities.py @@ -34,7 +34,6 @@ def test_HeavyQuarks(): def test_HeavyInfo(): i = hq.HeavyInfo( num_flavs_init=4, - intrinsic_flavors=[4, 5], masses=hq.HeavyQuarkMasses( [ hq.QuarkMassRef([2.0, nan]), From 7279e86333bf09043c8c161144561f6074b3c230 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 11:40:59 +0200 Subject: [PATCH 22/67] Compute always intrinsic in ome --- .../operator_matrix_element.py | 24 +++++++++---------- tests/eko/evolution_operator/test_ome.py | 1 + 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index b45e06c81..fc0518aa1 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -234,11 +234,10 @@ def labels(self): logger.warning("%s: skipping non-singlet sector", self.log_label) else: labels.append((200, 200)) - if self.backward_method is not None: - # intrinsic labels, which are not zero at NLO - labels.append((br.matching_hminus_pid, br.matching_hminus_pid)) - # These contributions are always 0 for the moment - # labels.extend([(200, br.matching_hminus_pid), (br.matching_hminus_pid, 200)]) + # intrinsic labels, which are not zero at NLO + labels.append((br.matching_hminus_pid, br.matching_hminus_pid)) + # These contributions are always 0 for the moment + # labels.extend([(200, br.matching_hminus_pid), (br.matching_hminus_pid, 200)]) # same for singlet if self.config["debug_skip_singlet"]: logger.warning("%s: skipping singlet sector", self.log_label) @@ -250,14 +249,13 @@ def labels(self): (br.matching_hplus_pid, 100), ] ) - if self.backward_method is not None: - labels.extend( - [ - (21, br.matching_hplus_pid), - (100, br.matching_hplus_pid), - (br.matching_hplus_pid, br.matching_hplus_pid), - ] - ) + labels.extend( + [ + (21, br.matching_hplus_pid), + (100, br.matching_hplus_pid), + (br.matching_hplus_pid, br.matching_hplus_pid), + ] + ) return labels def quad_ker(self, label, logx, areas): diff --git a/tests/eko/evolution_operator/test_ome.py b/tests/eko/evolution_operator/test_ome.py index b844290c9..c90563269 100644 --- a/tests/eko/evolution_operator/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -338,6 +338,7 @@ def test_labels(self, theory_ffns, operator_card, tmp_path: pathlib.Path): path = tmp_path / "eko.tar" for skip_singlet in [True, False]: for skip_ns in [True, False]: + operator_card.configs.inversion_method = "exact" operator_card.debug.skip_singlet = skip_singlet operator_card.debug.skip_non_singlet = skip_ns path.unlink(missing_ok=True) From da9fbc42da4ee62823f80031efba037a0e9e8642 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 12:08:15 +0200 Subject: [PATCH 23/67] Move eko.io.runcards.update --- src/eko/io/runcards.py | 22 -------- src/eko/runner/legacy.py | 4 +- src/ekomark/data/__init__.py | 28 ++++++++++ tests/eko/io/test_runcards.py | 88 ------------------------------ tests/ekomark/data/__init__.py | 0 tests/ekomark/data/test_init.py | 96 +++++++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 111 deletions(-) create mode 100644 tests/ekomark/data/__init__.py create mode 100644 tests/ekomark/data/test_init.py diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index d5c8c36e8..8a6261bf2 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -255,28 +255,6 @@ def new_operator(self): return OperatorCard.from_dict(new) -def update(theory: Union[RawCard, TheoryCard], operator: Union[RawCard, OperatorCard]): - """Update legacy runcards. - - This function is mainly defined for compatibility with the old interface. - Prefer direct usage of :class:`Legacy` in new code. - - Consecutive applications of this function yield identical results:: - - cards = update(theory, operator) - assert update(*cards) == cards - - """ - if isinstance(theory, TheoryCard) or isinstance(operator, OperatorCard): - # if one is not a dict, both have to be new cards - assert isinstance(theory, TheoryCard) - assert isinstance(operator, OperatorCard) - return theory, operator - - cards = Legacy(theory, operator) - return cards.new_theory, cards.new_operator - - def default_atlas(masses: list, matching_ratios: list): r"""Create default landscape. diff --git a/src/eko/runner/legacy.py b/src/eko/runner/legacy.py index 76d6f1a8a..5de53ceb7 100644 --- a/src/eko/runner/legacy.py +++ b/src/eko/runner/legacy.py @@ -3,6 +3,8 @@ import os from typing import Union +from ekomark.data import update_runcards + from ..evolution_operator.grid import OperatorGrid from ..io import EKO, Operator, runcards from ..io.types import RawCard @@ -43,7 +45,7 @@ def __init__( path where to store the computed operator """ - new_theory, new_operator = runcards.update(theory_card, operators_card) + new_theory, new_operator = update_runcards(theory_card, operators_card) # Store inputs self.path = path diff --git a/src/ekomark/data/__init__.py b/src/ekomark/data/__init__.py index 797409204..b6242845b 100644 --- a/src/ekomark/data/__init__.py +++ b/src/ekomark/data/__init__.py @@ -1 +1,29 @@ """EKO database configuration.""" +from typing import Union + +from eko.io.runcards import Legacy, OperatorCard, TheoryCard +from eko.io.types import RawCard + + +def update_runcards( + theory: Union[RawCard, TheoryCard], operator: Union[RawCard, OperatorCard] +): + """Update legacy runcards. + + This function is mainly defined for compatibility with the old interface. + Prefer direct usage of :class:`Legacy` in new code. + + Consecutive applications of this function yield identical results:: + + cards = update(theory, operator) + assert update(*cards) == cards + + """ + if isinstance(theory, TheoryCard) or isinstance(operator, OperatorCard): + # if one is not a dict, both have to be new cards + assert isinstance(theory, TheoryCard) + assert isinstance(operator, OperatorCard) + return theory, operator + + cards = Legacy(theory, operator) + return cards.new_theory, cards.new_operator diff --git a/tests/eko/io/test_runcards.py b/tests/eko/io/test_runcards.py index 0a391047b..465a1abf6 100644 --- a/tests/eko/io/test_runcards.py +++ b/tests/eko/io/test_runcards.py @@ -1,14 +1,11 @@ -import copy from io import StringIO import numpy as np import pytest import yaml -from banana.data.theories import default_card as theory_card from eko.io import runcards as rc from eko.io.bases import Bases -from ekomark.data.operators import default_card as operator_card def test_flavored_mu2grid(): @@ -31,48 +28,6 @@ def test_flavored_mu2grid(): assert t == tuple(l) -def test_runcards_opcard(): - # check conversion - tc = copy.deepcopy(theory_card) - oc = copy.deepcopy(operator_card) - tc["Q0"] = 2.0 - # mugrid - oc["mugrid"] = [2.0, 10.0] - _nt, no = rc.update(tc, oc) - assert isinstance(no, rc.OperatorCard) - assert len(no.evolgrid) == len(oc["mugrid"]) - assert len(no.mu2grid) == len(no.evolgrid) - assert no.evolgrid[0][-1] == 4 - assert no.evolgrid[1][-1] == 5 - np.testing.assert_allclose(no.mu0, tc["Q0"]) - np.testing.assert_allclose(no.mu20, tc["Q0"] ** 2.0) - assert len(no.pids) == 14 - check_dumpable(no) - del oc["mugrid"] - # or mu2grid - oc["mu2grid"] = [9.0, 30.0, 32.0] - _nt, no = rc.update(tc, oc) - assert isinstance(no, rc.OperatorCard) - assert len(no.evolgrid) == len(oc["mu2grid"]) - assert len(no.mu2grid) == len(no.evolgrid) - assert no.evolgrid[0][-1] == 4 - assert no.evolgrid[1][-1] == 5 - assert no.evolgrid[2][-1] == 5 - check_dumpable(no) - del oc["mu2grid"] - # or Q2grid - oc["Q2grid"] = [15.0, 130.0, 140.0, 1e5] - _nt, no = rc.update(tc, oc) - assert isinstance(no, rc.OperatorCard) - assert len(no.evolgrid) == len(oc["Q2grid"]) - assert len(no.mu2grid) == len(no.evolgrid) - assert no.evolgrid[0][-1] == 4 - assert no.evolgrid[1][-1] == 5 - assert no.evolgrid[2][-1] == 5 - assert no.evolgrid[3][-1] == 6 - check_dumpable(no) - - def check_dumpable(no): """Check we can write and read to yaml.""" so = StringIO() @@ -81,49 +36,6 @@ def check_dumpable(no): noo = yaml.safe_load(so) -def test_runcards_ekomark(): - # check conversion - tc = copy.deepcopy(theory_card) - oc = copy.deepcopy(operator_card) - nt, no = rc.update(tc, oc) - assert isinstance(nt, rc.TheoryCard) - assert isinstance(no, rc.OperatorCard) - # check is idempotent - nnt, nno = rc.update(nt, no) - assert nnt == nt - assert nno == no - - -def test_runcards_quarkmass(): - tc = copy.deepcopy(theory_card) - tc["nfref"] = 5 - tc["IC"] = 1 - oc = copy.deepcopy(operator_card) - nt, no = rc.update(tc, oc) - for _, scale in nt.heavy.masses: - assert np.isnan(scale) - m2s = rc.masses(nt, no.configs.evolution_method) - raw = rc.Legacy.heavies("m%s", tc) - raw2 = np.power(raw, 2.0) - np.testing.assert_allclose(m2s, raw2) - tc["HQ"] = "MSBAR" - tc["Qmc"] = raw[0] * 1.1 - tc["Qmb"] = raw[1] * 1.1 - tc["Qmt"] = raw[2] * 0.9 - nt, no = rc.update(tc, oc) - for _, scale in nt.heavy.masses: - assert not np.isnan(scale) - m2s = rc.masses(nt, no.configs.evolution_method) - for m1, m2 in zip(m2s, raw2): - assert not np.isclose(m1, m2) - tc["HQ"] = "Blub" - with pytest.raises(ValueError, match="mass scheme"): - _nt, _no = rc.update(tc, oc) - nt.heavy.masses_scheme = "Bla" - with pytest.raises(ValueError, match="mass scheme"): - _ms = rc.masses(nt, no.configs.evolution_method) - - def test_legacy_fallback(): assert rc.Legacy.fallback(1, 2, 3) == 1 assert rc.Legacy.fallback(None, 2, 3) == 2 diff --git a/tests/ekomark/data/__init__.py b/tests/ekomark/data/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ekomark/data/test_init.py b/tests/ekomark/data/test_init.py new file mode 100644 index 000000000..7d39dca43 --- /dev/null +++ b/tests/ekomark/data/test_init.py @@ -0,0 +1,96 @@ +import copy + +import numpy as np +import pytest +from banana.data.theories import default_card as theory_card + +from eko.io import runcards as rc +from ekomark.data import update_runcards +from ekomark.data.operators import default_card as operator_card + +from ...eko.io.test_runcards import check_dumpable + + +def test_runcards_opcard(): + # check conversion + tc = copy.deepcopy(theory_card) + oc = copy.deepcopy(operator_card) + tc["Q0"] = 2.0 + # mugrid + oc["mugrid"] = [2.0, 10.0] + _nt, no = update_runcards(tc, oc) + assert isinstance(no, rc.OperatorCard) + assert len(no.evolgrid) == len(oc["mugrid"]) + assert len(no.mu2grid) == len(no.evolgrid) + assert no.evolgrid[0][-1] == 4 + assert no.evolgrid[1][-1] == 5 + np.testing.assert_allclose(no.mu0, tc["Q0"]) + np.testing.assert_allclose(no.mu20, tc["Q0"] ** 2.0) + assert len(no.pids) == 14 + check_dumpable(no) + del oc["mugrid"] + # or mu2grid + oc["mu2grid"] = [9.0, 30.0, 32.0] + _nt, no = update_runcards(tc, oc) + assert isinstance(no, rc.OperatorCard) + assert len(no.evolgrid) == len(oc["mu2grid"]) + assert len(no.mu2grid) == len(no.evolgrid) + assert no.evolgrid[0][-1] == 4 + assert no.evolgrid[1][-1] == 5 + assert no.evolgrid[2][-1] == 5 + check_dumpable(no) + del oc["mu2grid"] + # or Q2grid + oc["Q2grid"] = [15.0, 130.0, 140.0, 1e5] + _nt, no = update_runcards(tc, oc) + assert isinstance(no, rc.OperatorCard) + assert len(no.evolgrid) == len(oc["Q2grid"]) + assert len(no.mu2grid) == len(no.evolgrid) + assert no.evolgrid[0][-1] == 4 + assert no.evolgrid[1][-1] == 5 + assert no.evolgrid[2][-1] == 5 + assert no.evolgrid[3][-1] == 6 + check_dumpable(no) + + +def test_runcards_ekomark(): + # check conversion + tc = copy.deepcopy(theory_card) + oc = copy.deepcopy(operator_card) + nt, no = update_runcards(tc, oc) + assert isinstance(nt, rc.TheoryCard) + assert isinstance(no, rc.OperatorCard) + # check is idempotent + nnt, nno = update_runcards(nt, no) + assert nnt == nt + assert nno == no + + +def test_runcards_quarkmass(): + tc = copy.deepcopy(theory_card) + tc["nfref"] = 5 + tc["IC"] = 1 + oc = copy.deepcopy(operator_card) + nt, no = update_runcards(tc, oc) + for _, scale in nt.heavy.masses: + assert np.isnan(scale) + m2s = rc.masses(nt, no.configs.evolution_method) + raw = rc.Legacy.heavies("m%s", tc) + raw2 = np.power(raw, 2.0) + np.testing.assert_allclose(m2s, raw2) + tc["HQ"] = "MSBAR" + tc["Qmc"] = raw[0] * 1.1 + tc["Qmb"] = raw[1] * 1.1 + tc["Qmt"] = raw[2] * 0.9 + nt, no = update_runcards(tc, oc) + for _, scale in nt.heavy.masses: + assert not np.isnan(scale) + m2s = rc.masses(nt, no.configs.evolution_method) + for m1, m2 in zip(m2s, raw2): + assert not np.isclose(m1, m2) + tc["HQ"] = "Blub" + with pytest.raises(ValueError, match="mass scheme"): + _nt, _no = update_runcards(tc, oc) + nt.heavy.masses_scheme = "Bla" + with pytest.raises(ValueError, match="mass scheme"): + _ms = rc.masses(nt, no.configs.evolution_method) From 1c448ffd6dd84b665a73b9a8b895c40b27b7d16e Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 1 Aug 2023 12:20:18 +0200 Subject: [PATCH 24/67] Define higher level interfaces for improved runners creation --- src/eko/runner/managed.py | 13 +++++-------- src/eko/runner/operators.py | 9 +++++++++ src/eko/runner/recipes.py | 15 ++++++++++++--- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/eko/runner/managed.py b/src/eko/runner/managed.py index c353decde..b21882d92 100644 --- a/src/eko/runner/managed.py +++ b/src/eko/runner/managed.py @@ -15,7 +15,7 @@ from ..io.items import Evolution, Matching, Target from ..io.runcards import OperatorCard, TheoryCard from ..io.struct import EKO -from . import commons, operators, parts, recipes +from . import operators, parts, recipes def solve(theory: TheoryCard, operator: OperatorCard, path: Path): @@ -24,11 +24,7 @@ def solve(theory: TheoryCard, operator: OperatorCard, path: Path): with EKO.create(path) as builder: eko = builder.load_cards(theory, operator).build() # pylint: disable=E1101 - - atlas = commons.atlas(eko.theory_card, eko.operator_card) - - recs = recipes.create(eko.operator_card.evolgrid, atlas) - eko.load_recipes(recs) + recipes.create(eko) for recipe in eko.recipes: assert isinstance(recipe, Evolution) @@ -42,8 +38,9 @@ def solve(theory: TheoryCard, operator: OperatorCard, path: Path): del eko.parts_matching[recipe] for ep in operator.evolgrid: - headers = recipes.elements(ep, atlas) - parts_ = operators.retrieve(headers, eko.parts, eko.parts_matching) + parts_ = operators.retrieve( + operators.parts(ep, eko), eko.parts, eko.parts_matching + ) target = Target.from_ep(ep) eko.operators[target] = operators.join(parts_) # flush the memory diff --git a/src/eko/runner/operators.py b/src/eko/runner/operators.py index 5a0a219c7..2ccbd1013 100644 --- a/src/eko/runner/operators.py +++ b/src/eko/runner/operators.py @@ -7,6 +7,9 @@ from ..io.inventory import Inventory from ..io.items import Evolution, Operator, Recipe +from ..io.struct import EKO +from ..io.types import EvolutionPoint +from . import commons, recipes def retrieve( @@ -91,3 +94,9 @@ def join(elements: List[Operator]) -> Operator: """ return reduce(dotop, reversed(elements)) + + +def parts(ep: EvolutionPoint, eko: EKO) -> List[Recipe]: + """Determine parts required for the given evolution point operator.""" + atlas = commons.atlas(eko.theory_card, eko.operator_card) + return recipes._elements(ep, atlas) diff --git a/src/eko/runner/recipes.py b/src/eko/runner/recipes.py index 7a09554cb..9c0b11170 100644 --- a/src/eko/runner/recipes.py +++ b/src/eko/runner/recipes.py @@ -2,11 +2,13 @@ from typing import List from ..io.items import Evolution, Matching, Recipe +from ..io.struct import EKO from ..io.types import EvolutionPoint as EPoint from ..matchings import Atlas, Segment +from . import commons -def elements(ep: EPoint, atlas: Atlas) -> List[Recipe]: +def _elements(ep: EPoint, atlas: Atlas) -> List[Recipe]: """Determine recipes to compute a given operator.""" recipes = [] @@ -26,10 +28,17 @@ def elements(ep: EPoint, atlas: Atlas) -> List[Recipe]: return recipes -def create(evolgrid: List[EPoint], atlas: Atlas) -> List[Recipe]: +def _create(evolgrid: List[EPoint], atlas: Atlas) -> List[Recipe]: """Create all associated recipes.""" recipes = [] for ep in evolgrid: - recipes.extend(elements(ep, atlas)) + recipes.extend(_elements(ep, atlas)) return list(set(recipes)) + + +def create(eko: EKO): + """Create and load all associated recipes.""" + atlas = commons.atlas(eko.theory_card, eko.operator_card) + recs = _create(eko.operator_card.evolgrid, atlas) + eko.load_recipes(recs) From e7268e927f08abb85d908ffd664f940315725856 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 1 Aug 2023 12:31:23 +0200 Subject: [PATCH 25/67] Fix recipes unit tests --- tests/eko/runner/test_recipes.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/eko/runner/test_recipes.py b/tests/eko/runner/test_recipes.py index 59b1a8855..20988f1c7 100644 --- a/tests/eko/runner/test_recipes.py +++ b/tests/eko/runner/test_recipes.py @@ -4,26 +4,26 @@ from eko.io.types import EvolutionPoint from eko.matchings import Atlas from eko.quantities.heavy_quarks import MatchingScales -from eko.runner.recipes import create, elements +from eko.runner.recipes import _create, _elements SCALES = MatchingScales([10.0, 20.0, 30.0]) ATLAS = Atlas(SCALES, (50.0, 5)) def test_elements(): - onestep = elements((60.0, 5), ATLAS) + onestep = _elements((60.0, 5), ATLAS) assert len(onestep) == 1 assert isinstance(onestep[0], Evolution) assert not onestep[0].cliff - backandforth = elements((60.0, 6), ATLAS) + backandforth = _elements((60.0, 6), ATLAS) assert len(backandforth) == 3 assert isinstance(backandforth[0], Evolution) assert backandforth[0].cliff assert isinstance(backandforth[1], Matching) assert not backandforth[1].inverse - down = elements((5.0, 3), ATLAS) + down = _elements((5.0, 3), ATLAS) assert all([isinstance(el, Evolution) for i, el in enumerate(down) if i % 2 == 0]) assert all([isinstance(el, Matching) for i, el in enumerate(down) if i % 2 == 1]) @@ -31,13 +31,13 @@ def test_elements(): def test_create(): evolgrid: List[EvolutionPoint] = [(60.0, 5)] - recs = create(evolgrid, ATLAS) + recs = _create(evolgrid, ATLAS) assert len(recs) == 1 evolgrid.append((60.0, 6)) - recs = create(evolgrid, ATLAS) + recs = _create(evolgrid, ATLAS) assert len(recs) == 1 + 3 evolgrid.append((70.0, 6)) - recs = create(evolgrid, ATLAS) + recs = _create(evolgrid, ATLAS) assert len(recs) == 1 + 3 + 1 From 075febb13fd5f3340c9094885ed7762413493896 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 1 Aug 2023 12:39:31 +0200 Subject: [PATCH 26/67] Fix runner conftest --- tests/eko/runner/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/eko/runner/conftest.py b/tests/eko/runner/conftest.py index a1516b2a7..6c513e3eb 100644 --- a/tests/eko/runner/conftest.py +++ b/tests/eko/runner/conftest.py @@ -28,7 +28,7 @@ def identity(neweko: EKO): @pytest.fixture def ekoparts(neweko: EKO, identity: Operator): atlas = commons.atlas(neweko.theory_card, neweko.operator_card) - neweko.load_recipes(recipes.create(neweko.operator_card.evolgrid, atlas)) + neweko.load_recipes(recipes._create(neweko.operator_card.evolgrid, atlas)) for rec in neweko.recipes: neweko.parts[rec] = identity From ac406cd3c0f956654a5f679e95fec0073bb55c00 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 12:40:16 +0200 Subject: [PATCH 27/67] Use EPoint in couplings --- benchmarks/eko/benchmark_evol_to_unity.py | 3 +-- benchmarks/eko/benchmark_msbar_evolution.py | 3 +-- benchmarks/eko/benchmark_strong_coupling.py | 8 +++----- benchmarks/ekobox/benchmark_evol_pdf.py | 4 ++-- doc/source/overview/tutorials/alpha_s.ipynb | 2 +- doc/source/overview/tutorials/pdf.ipynb | 3 +-- extras/n3lo_bench/splitting_function_utils.py | 3 +-- src/eko/couplings.py | 6 +++--- src/eko/io/runcards.py | 3 +-- src/eko/msbar_masses.py | 4 ++-- src/eko/quantities/couplings.py | 10 ++-------- src/ekobox/cards.py | 3 +-- src/ekobox/info_file.py | 2 +- tests/eko/kernels/test_kernels_QEDns.py | 3 +-- tests/eko/quantities/test_couplings.py | 4 ++-- tests/eko/runner/test_legacy.py | 2 +- tests/eko/test_couplings.py | 17 ++++++----------- tests/eko/test_msbar_masses.py | 3 +-- 18 files changed, 31 insertions(+), 52 deletions(-) diff --git a/benchmarks/eko/benchmark_evol_to_unity.py b/benchmarks/eko/benchmark_evol_to_unity.py index d269db202..5e864b3b5 100644 --- a/benchmarks/eko/benchmark_evol_to_unity.py +++ b/benchmarks/eko/benchmark_evol_to_unity.py @@ -19,8 +19,7 @@ def update_cards(theory: TheoryCard, operator: OperatorCard): theory.couplings = CouplingsInfo( alphas=0.35, alphaem=0.007496, - scale=float(np.sqrt(2)), - num_flavs_ref=None, + scale=(float(np.sqrt(2)), 4), ) theory.heavy.num_flavs_init = 4 theory.heavy.masses.c.value = 1.0 diff --git a/benchmarks/eko/benchmark_msbar_evolution.py b/benchmarks/eko/benchmark_msbar_evolution.py index 6286e15ad..86e0e361e 100644 --- a/benchmarks/eko/benchmark_msbar_evolution.py +++ b/benchmarks/eko/benchmark_msbar_evolution.py @@ -20,9 +20,8 @@ def update_theory(theory: TheoryCard): theory.order = (3, 0) - theory.couplings.scale = 91 + theory.couplings.ref = (91, 5) theory.couplings.alphaem = 0.007496 - theory.couplings.num_flavs_ref = 5 theory.heavy.masses_scheme = QuarkMassScheme.MSBAR theory.heavy.masses.c = QuarkMassRef([1.5, 18]) theory.heavy.masses.b = QuarkMassRef([4.1, 20]) diff --git a/benchmarks/eko/benchmark_strong_coupling.py b/benchmarks/eko/benchmark_strong_coupling.py index 80f65cf72..3f94bd036 100644 --- a/benchmarks/eko/benchmark_strong_coupling.py +++ b/benchmarks/eko/benchmark_strong_coupling.py @@ -39,8 +39,7 @@ def ref_couplings(ref_values, ref_scale: float, ref_nf: FlavorsNumber) -> Coupli return CouplingsInfo( alphas=ref_values[0], alphaem=ref_values[1], - scale=ref_scale, - num_flavs_ref=ref_nf, + ref=(ref_scale, ref_nf), ) @@ -841,9 +840,8 @@ def benchmark_APFEL_fact_to_ren_lha_settings(self, theory_card: TheoryCard): theory = theory_card theory.order = (3, 0) theory.couplings.alphas = 0.35 - theory.couplings.scale = float(np.sqrt(2)) theory.couplings.alphaem = 0.007496 - theory.couplings.num_flavs_ref = 4 + theory.couplings.ref = (float(np.sqrt(2)), 4) theory.heavy.num_flavs_init = 3 theory.xif = np.sqrt(1.0 / 2.0) theory.heavy.masses.c.value = np.sqrt(2.0) @@ -886,7 +884,7 @@ def benchmark_APFEL_fact_to_ren_lha_settings(self, theory_card: TheoryCard): apfel.SetTheory("QCD") apfel.SetPerturbativeOrder(theory.order[0] - 1) apfel.SetAlphaEvolution("exact") - apfel.SetAlphaQCDRef(theory.couplings.alphas, theory.couplings.scale) + apfel.SetAlphaQCDRef(theory.couplings.alphas, theory.couplings.ref[0]) apfel.SetVFNS() apfel.SetPoleMasses(qmasses.c.value, qmasses.b.value, qmasses.t.value) apfel.SetMassMatchingScales( diff --git a/benchmarks/ekobox/benchmark_evol_pdf.py b/benchmarks/ekobox/benchmark_evol_pdf.py index c85083604..5d198b3ff 100644 --- a/benchmarks/ekobox/benchmark_evol_pdf.py +++ b/benchmarks/ekobox/benchmark_evol_pdf.py @@ -21,7 +21,7 @@ def benchmark_evolve_single_member( theory = theory_card theory.order = (1, 0) theory.couplings.alphas = 0.118000 - theory.couplings.scale = 91.1876 + theory.couplings.ref = (91.1876, 5) theory.couplings.alphaem = 0.007496 theory.heavy.masses.c.value = 1.3 theory.heavy.masses.b.value = 4.75 @@ -47,7 +47,7 @@ def benchmark_evolve_single_member( ev_pdf = lhapdf.mkPDF("EvPDF", 0) assert info["XMin"] == op.xgrid.raw[0] assert info["SetDesc"] == "MyEvolvedPDF" - assert info["MZ"] == theory.couplings.scale + assert info["MZ"] == theory.couplings.ref[0] assert info["Debug"] == "Debug" xgrid = op.xgrid.raw for idx, mu2 in enumerate(op.mu2grid): diff --git a/doc/source/overview/tutorials/alpha_s.ipynb b/doc/source/overview/tutorials/alpha_s.ipynb index d8954900d..327eb39c9 100644 --- a/doc/source/overview/tutorials/alpha_s.ipynb +++ b/doc/source/overview/tutorials/alpha_s.ipynb @@ -40,7 +40,7 @@ "\n", "# set the (alpha_s, alpha_em) reference values\n", "couplings_ref = CouplingsInfo(\n", - " alphas=0.118, alphaem=0.007496252, scale=91.0, num_flavs_ref=5\n", + " alphas=0.118, alphaem=0.007496252, ref=(91.0, 5)\n", ")\n", "\n", "# set heavy quark masses and their threshold ratios\n", diff --git a/doc/source/overview/tutorials/pdf.ipynb b/doc/source/overview/tutorials/pdf.ipynb index 0719d9d63..2cc2f688b 100644 --- a/doc/source/overview/tutorials/pdf.ipynb +++ b/doc/source/overview/tutorials/pdf.ipynb @@ -369,8 +369,7 @@ "th_card.orders = (1,0) # QCD LO\n", "th_card.heavy.masses = HeavyQuarks([QuarkMassRef([1.3,nan]), QuarkMassRef([4.75,nan]), QuarkMassRef([172.,nan])]) # quark mass\n", "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", - "th_card.couplings.scale = 91.1876 # the reference scale at which alpha_s is provided\n", - "th_card.couplings.num_flavs_ref = 5 # the number of flavors active at the alpha_s reference scale\n", + "th_card.couplings.ref = (91.1876,5) # the reference scale together with the number of flavors at which alpha_s is provided\n", "th_card.heavy.num_flavs_init = 3 # the number of flavors active at the reference scale" ] }, diff --git a/extras/n3lo_bench/splitting_function_utils.py b/extras/n3lo_bench/splitting_function_utils.py index db06f5c72..7368e24b1 100644 --- a/extras/n3lo_bench/splitting_function_utils.py +++ b/extras/n3lo_bench/splitting_function_utils.py @@ -103,8 +103,7 @@ def compute_a_s(q2=None, xif2=1.0, nf=None, order=(4, 0)): ref = CouplingsInfo( alphas=0.1181, alphaem=0.007496, - scale=91.00, - num_flavs_ref=5, + ref=(91.00, 5), ) sc = Couplings( couplings=ref, diff --git a/src/eko/couplings.py b/src/eko/couplings.py index 1b3620032..3bf21b11d 100644 --- a/src/eko/couplings.py +++ b/src/eko/couplings.py @@ -435,7 +435,7 @@ def assert_positive(name, var): assert_positive("alpha_s_ref", couplings.alphas) assert_positive("alpha_em_ref", couplings.alphaem) - assert_positive("scale_ref", couplings.scale) + assert_positive("scale_ref", couplings.ref[0]) if order[0] not in [1, 2, 3, 4]: raise NotImplementedError("a_s beyond N3LO is not implemented") if order[1] not in [0, 1, 2]: @@ -445,7 +445,7 @@ def assert_positive(name, var): raise ValueError(f"Unknown method {method.value}") self.method = method.value - nf_ref = couplings.num_flavs_ref + nf_ref = couplings.ref[1] scheme_name = hqm_scheme.name self.alphaem_running = couplings.em_running self.decoupled_running = False @@ -454,7 +454,7 @@ def assert_positive(name, var): self.a_ref = np.array(couplings.values) / 4.0 / np.pi # convert to a_s and a_em matching_scales = (np.array(masses) * np.array(thresholds_ratios)).tolist() self.thresholds_ratios = list(thresholds_ratios) - self.atlas = matchings.Atlas(matching_scales, (couplings.scale**2, nf_ref)) + self.atlas = matchings.Atlas(matching_scales, (couplings.ref[0] ** 2, nf_ref)) self.hqm_scheme = scheme_name logger.info( "Strong Coupling: a_s(µ_R^2=%f)%s=%f=%f/(4π)", diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index 8a6261bf2..3d8413d1b 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -183,8 +183,7 @@ def new_theory(self): alphas=old["alphas"], alphaem=alphaem, em_running=em_running, - scale=old["Qref"], - num_flavs_ref=old["nfref"], + ref=(old["Qref"], old["nfref"]), ) new["heavy"] = { "num_flavs_init": nf_default(old["Q0"] ** 2.0, default_atlas(ms, ks)) diff --git a/src/eko/msbar_masses.py b/src/eko/msbar_masses.py index f13582110..5edac4c46 100644 --- a/src/eko/msbar_masses.py +++ b/src/eko/msbar_masses.py @@ -377,8 +377,8 @@ def compute( """ # TODO: sketch in the docs how the MSbar computation works with a figure. - mu2_ref = couplings.scale**2 - nf_ref: FlavorsNumber = couplings.num_flavs_ref + mu2_ref = couplings.ref[0] ** 2 + nf_ref: FlavorsNumber = couplings.ref[1] masses = np.concatenate((np.zeros(nf_ref - 3), np.full(6 - nf_ref, np.inf))) def sc(thr_masses): diff --git a/src/eko/quantities/couplings.py b/src/eko/quantities/couplings.py index f80420a9c..3a5ab96ef 100644 --- a/src/eko/quantities/couplings.py +++ b/src/eko/quantities/couplings.py @@ -3,6 +3,7 @@ import enum from ..io.dictlike import DictLike +from ..io.types import EvolutionPoint as EPoint from ..io.types import FlavorsNumber, LinearScale, ReferenceRunning, Scalar Coupling = Scalar @@ -19,14 +20,7 @@ class CouplingsInfo(DictLike): alphas: Coupling alphaem: Coupling - scale: LinearScale - num_flavs_ref: FlavorsNumber - r"""Number of active flavors at strong coupling reference scale. - - I.e. :math:`n_{f,\text{ref}}(\mu^2_{\text{ref}})`, formerly called - ``nfref``. - - """ + ref: EPoint em_running: bool = False @property diff --git a/src/ekobox/cards.py b/src/ekobox/cards.py index 482e65faf..3d4e346aa 100644 --- a/src/ekobox/cards.py +++ b/src/ekobox/cards.py @@ -13,8 +13,7 @@ couplings=dict( alphas=0.118, alphaem=0.007496252, - scale=91.2, - num_flavs_ref=5, + ref=(91.2, 5), ), heavy=dict( num_flavs_init=4, diff --git a/src/ekobox/info_file.py b/src/ekobox/info_file.py index 2f99d8377..35f2cfcae 100644 --- a/src/ekobox/info_file.py +++ b/src/ekobox/info_file.py @@ -48,7 +48,7 @@ def build( template_info["OrderQCD"] = theory_card.order[0] - 1 template_info["QMin"] = round(math.sqrt(operators_card.mu2grid[0]), 4) template_info["QMax"] = round(math.sqrt(operators_card.mu2grid[-1]), 4) - template_info["MZ"] = theory_card.couplings.scale + template_info["MZ"] = theory_card.couplings.ref[0] template_info["MUp"] = 0.0 template_info["MDown"] = 0.0 template_info["MStrange"] = 0.0 diff --git a/tests/eko/kernels/test_kernels_QEDns.py b/tests/eko/kernels/test_kernels_QEDns.py index b85a3f013..2e710c722 100644 --- a/tests/eko/kernels/test_kernels_QEDns.py +++ b/tests/eko/kernels/test_kernels_QEDns.py @@ -119,8 +119,7 @@ def test_zero_true_gamma(): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=5, + ref=(muref, 5), ) ) evmod = CouplingEvolutionMethod.EXACT diff --git a/tests/eko/quantities/test_couplings.py b/tests/eko/quantities/test_couplings.py index 83bef709c..e4d194d5b 100644 --- a/tests/eko/quantities/test_couplings.py +++ b/tests/eko/quantities/test_couplings.py @@ -3,7 +3,7 @@ def test_couplings_ref(): scale = 90.0 - d = dict(alphas=0.1, alphaem=0.01, scale=scale, num_flavs_ref=5) + d = dict(alphas=0.1, alphaem=0.01, ref=(scale, 5)) couplings = CouplingsInfo.from_dict(d) - assert couplings.scale == scale + assert couplings.ref[0] == scale assert not couplings.em_running diff --git a/tests/eko/runner/test_legacy.py b/tests/eko/runner/test_legacy.py index 60395acc5..1828285c3 100644 --- a/tests/eko/runner/test_legacy.py +++ b/tests/eko/runner/test_legacy.py @@ -36,7 +36,7 @@ class FakeEM(enum.Enum): eko.runner.legacy.Runner(theory_card, operator_card, path=path) # MSbar scheme theory_card.heavy.masses_scheme = QuarkMassScheme.MSBAR - theory_card.couplings.num_flavs_ref = 5 + theory_card.couplings.ref = (91.0, 5) theory_card.heavy.masses.c.scale = 2 theory_card.heavy.masses.b.scale = 4.5 theory_card.heavy.masses.t.scale = 173.07 diff --git a/tests/eko/test_couplings.py b/tests/eko/test_couplings.py index 10535cbcb..7468051be 100644 --- a/tests/eko/test_couplings.py +++ b/tests/eko/test_couplings.py @@ -53,8 +53,7 @@ def test_init(self): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=5, + ref=(muref, 5), ) ) order = (1, 0) @@ -107,7 +106,7 @@ def test_init(self): ) with pytest.raises(ValueError): coup3 = copy.deepcopy(couplings) - coup3.scale = 0 + coup3.ref = (0.0, 5) Couplings( coup3, order, @@ -159,8 +158,7 @@ def test_ref(self): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=nfref, + ref=(muref, nfref), ) ) for order_s in [1, 2, 3, 4]: @@ -193,8 +191,7 @@ def test_ref_copy_e841b0dfdee2f31d9ccc1ecee4d9d1a6f6624313(self): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=3, # reference nf is needed to force the matching + ref=(muref, 3), # reference nf is needed to force the matching ) ) sc = Couplings( @@ -233,8 +230,7 @@ def test_exact(self): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=nfref, + ref=(muref, nfref), em_running=em_running, ) ) @@ -295,8 +291,7 @@ def benchmark_expanded_n3lo(self): couplings = CouplingsInfo( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=5, + ref=(muref, 5), ) m2c = 2 m2b = 25 diff --git a/tests/eko/test_msbar_masses.py b/tests/eko/test_msbar_masses.py index b0c102ef8..edfd243ab 100644 --- a/tests/eko/test_msbar_masses.py +++ b/tests/eko/test_msbar_masses.py @@ -15,9 +15,8 @@ def theory_card(theory_card: TheoryCard): th = theory_card th.order = (3, 0) th.couplings.alphas = 0.1180 - th.couplings.scale = 91.0 th.couplings.alphaem = 0.00781 - th.couplings.num_flavs_ref = 5 + th.couplings.ref = (91.0, 5) th.heavy.masses = HeavyQuarkMasses( [QuarkMassRef(val) for val in [(2.0, 2.1), (4.0, 4.1), (175.0, 174.9)]] ) From 45ae33043c33435ae5231e34785d1572cd774fe7 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 15:04:11 +0200 Subject: [PATCH 28/67] Fix couplings ref ep in benchmarks --- benchmarks/eko/benchmark_evol_to_unity.py | 2 +- benchmarks/eko/benchmark_msbar_evolution.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmarks/eko/benchmark_evol_to_unity.py b/benchmarks/eko/benchmark_evol_to_unity.py index 5e864b3b5..561721f6f 100644 --- a/benchmarks/eko/benchmark_evol_to_unity.py +++ b/benchmarks/eko/benchmark_evol_to_unity.py @@ -19,7 +19,7 @@ def update_cards(theory: TheoryCard, operator: OperatorCard): theory.couplings = CouplingsInfo( alphas=0.35, alphaem=0.007496, - scale=(float(np.sqrt(2)), 4), + ref=(float(np.sqrt(2)), 4), ) theory.heavy.num_flavs_init = 4 theory.heavy.masses.c.value = 1.0 diff --git a/benchmarks/eko/benchmark_msbar_evolution.py b/benchmarks/eko/benchmark_msbar_evolution.py index 86e0e361e..c0e849e64 100644 --- a/benchmarks/eko/benchmark_msbar_evolution.py +++ b/benchmarks/eko/benchmark_msbar_evolution.py @@ -148,7 +148,7 @@ def benchmark_APFEL_msbar_evolution( apfel.SetTheory("QCD") apfel.SetPerturbativeOrder(order - 1) apfel.SetAlphaEvolution(method) - apfel.SetAlphaQCDRef(coupl.alphas, coupl.scale) + apfel.SetAlphaQCDRef(coupl.alphas, coupl.ref[0]) apfel.SetVFNS() apfel.SetMSbarMasses( qmasses.c.value, qmasses.b.value, qmasses.t.value @@ -216,7 +216,7 @@ def benchmark_APFEL_msbar_solution( apfel.SetTheory("QCD") apfel.SetPerturbativeOrder(order - 1) apfel.SetAlphaEvolution("exact") - apfel.SetAlphaQCDRef(coupl.alphas, coupl.scale) + apfel.SetAlphaQCDRef(coupl.alphas, coupl.ref[0]) apfel.SetVFNS() apfel.SetMSbarMasses(qmasses.c.value, qmasses.b.value, qmasses.t.value) apfel.SetMassScaleReference( From 0f94cdc66171c769c14dbd77052efdc44ea4f029 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 15:38:24 +0200 Subject: [PATCH 29/67] Use EPoint for PDF boundary --- benchmarks/eko/benchmark_evol_to_unity.py | 3 +-- benchmarks/eko/benchmark_strong_coupling.py | 1 - benchmarks/ekobox/benchmark_evol_pdf.py | 4 ++-- doc/source/overview/tutorials/pdf.ipynb | 5 ++--- src/eko/io/legacy.py | 7 +++---- src/eko/io/runcards.py | 22 ++++++++++----------- src/eko/io/struct.py | 2 +- src/eko/quantities/heavy_quarks.py | 6 ------ src/eko/runner/commons.py | 2 +- src/ekobox/cards.py | 3 +-- src/ekobox/cli/runcards.py | 2 +- src/ekobox/info_file.py | 4 +++- src/ekobox/utils.py | 2 +- tests/eko/evolution_operator/test_grid.py | 2 +- tests/eko/io/test_manipulate.py | 2 +- tests/eko/test_quantities.py | 1 - tests/ekobox/test_cards.py | 8 ++++---- tests/ekobox/test_evol_pdf.py | 2 +- tests/ekobox/test_info_file.py | 2 +- tests/ekobox/test_utils.py | 7 +++---- tests/ekomark/data/test_init.py | 2 +- 21 files changed, 39 insertions(+), 50 deletions(-) diff --git a/benchmarks/eko/benchmark_evol_to_unity.py b/benchmarks/eko/benchmark_evol_to_unity.py index 561721f6f..c466d00d8 100644 --- a/benchmarks/eko/benchmark_evol_to_unity.py +++ b/benchmarks/eko/benchmark_evol_to_unity.py @@ -21,11 +21,10 @@ def update_cards(theory: TheoryCard, operator: OperatorCard): alphaem=0.007496, ref=(float(np.sqrt(2)), 4), ) - theory.heavy.num_flavs_init = 4 theory.heavy.masses.c.value = 1.0 theory.heavy.masses.b.value = 4.75 theory.heavy.masses.t.value = 173.0 - operator.mu0 = float(np.sqrt(2)) + operator.init = (float(np.sqrt(2)), 4) operator.mugrid = [(10, 5)] operator.xgrid = XGrid(np.linspace(1e-1, 1, 30)) operator.configs.interpolation_polynomial_degree = 1 diff --git a/benchmarks/eko/benchmark_strong_coupling.py b/benchmarks/eko/benchmark_strong_coupling.py index 3f94bd036..1d1cd7219 100644 --- a/benchmarks/eko/benchmark_strong_coupling.py +++ b/benchmarks/eko/benchmark_strong_coupling.py @@ -842,7 +842,6 @@ def benchmark_APFEL_fact_to_ren_lha_settings(self, theory_card: TheoryCard): theory.couplings.alphas = 0.35 theory.couplings.alphaem = 0.007496 theory.couplings.ref = (float(np.sqrt(2)), 4) - theory.heavy.num_flavs_init = 3 theory.xif = np.sqrt(1.0 / 2.0) theory.heavy.masses.c.value = np.sqrt(2.0) theory.heavy.masses.b.value = 4.5 diff --git a/benchmarks/ekobox/benchmark_evol_pdf.py b/benchmarks/ekobox/benchmark_evol_pdf.py index 5d198b3ff..a0ddcaac4 100644 --- a/benchmarks/ekobox/benchmark_evol_pdf.py +++ b/benchmarks/ekobox/benchmark_evol_pdf.py @@ -27,7 +27,7 @@ def benchmark_evolve_single_member( theory.heavy.masses.b.value = 4.75 theory.heavy.masses.t.value = 172 op = operator_card - op.mu0 = 5.0 + op.init = (5.0, 4) op.mugrid = mugrid # lhapdf import (maybe i have to dump with a x*), do plots) with lhapdf_path(test_pdf): @@ -74,7 +74,7 @@ def benchmark_evolve_more_members( theory = theory_card theory.order = (1, 0) op = operator_card - op.mu0 = 1.0 + op.init = (1.0, 3) op.mugrid = [(10.0, 5), (100.0, 5)] op.xgrid = XGrid([1e-7, 0.01, 0.1, 0.2, 0.3]) with lhapdf_path(test_pdf): diff --git a/doc/source/overview/tutorials/pdf.ipynb b/doc/source/overview/tutorials/pdf.ipynb index 2cc2f688b..923520f59 100644 --- a/doc/source/overview/tutorials/pdf.ipynb +++ b/doc/source/overview/tutorials/pdf.ipynb @@ -361,7 +361,7 @@ "op_card = example.operator()\n", "op_card.xgrid = eko.interpolation.XGrid(make_grid(30, 30)) # x grid\n", "op_card.mugrid = [(float(q),5) for q in np.geomspace(5., 100, 5)] # Q2 grid\n", - "op_card.mu0 = 1.295000 # starting point for the evolution \n", + "op_card.init = (1.295000,3) # starting point for the evolution \n", "\n", "# setup the theory card - this can be mostly inferred from the PDF's .info file\n", "\n", @@ -369,8 +369,7 @@ "th_card.orders = (1,0) # QCD LO\n", "th_card.heavy.masses = HeavyQuarks([QuarkMassRef([1.3,nan]), QuarkMassRef([4.75,nan]), QuarkMassRef([172.,nan])]) # quark mass\n", "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", - "th_card.couplings.ref = (91.1876,5) # the reference scale together with the number of flavors at which alpha_s is provided\n", - "th_card.heavy.num_flavs_init = 3 # the number of flavors active at the reference scale" + "th_card.couplings.ref = (91.1876,5) # the reference scale together with the number of flavors at which alpha_s is provided" ] }, { diff --git a/src/eko/io/legacy.py b/src/eko/io/legacy.py index 8491a6acc..3bee940ac 100644 --- a/src/eko/io/legacy.py +++ b/src/eko/io/legacy.py @@ -99,7 +99,6 @@ class PseudoTheory(DictLike): def from_old(cls, old: RawCard): """Load from old metadata.""" heavy = HeavyInfo( - num_flavs_init=4, masses=HeavyQuarkMasses( [ ReferenceRunning([_MC, np.inf]), @@ -122,7 +121,7 @@ class PseudoOperator(DictLike): """ - mu20: float + init: EPoint evolgrid: List[EPoint] xgrid: XGrid configs: dict @@ -130,7 +129,7 @@ class PseudoOperator(DictLike): @classmethod def from_old(cls, old: RawCard): """Load from old metadata.""" - mu20 = float(old["q2_ref"]) + mu0 = float(np.sqrt(float(old["q2_ref"]))) mu2list = old.get("Q2grid") if mu2list is None: mu2list = old["mu2grid"] @@ -146,7 +145,7 @@ def from_old(cls, old: RawCard): interpolation_is_log=old.get("interpolation_is_log"), ) - return cls(mu20=mu20, evolgrid=evolgrid, xgrid=xgrid, configs=configs) + return cls(init=(mu0, 4), evolgrid=evolgrid, xgrid=xgrid, configs=configs) ARRAY_SUFFIX = ".npy.lz4" diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index 3d8413d1b..8ab9beeff 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -95,7 +95,7 @@ class Configs(DictLike): class OperatorCard(DictLike): """Operator Card info.""" - mu0: float + init: EPoint """Initial scale.""" mugrid: List[EPoint] xgrid: interpolation.XGrid @@ -115,7 +115,7 @@ class OperatorCard(DictLike): @property def mu20(self): """Squared value of initial scale.""" - return self.mu0**2 + return self.init[0] ** 2 @property def mu2grid(self) -> npt.NDArray: @@ -186,9 +186,6 @@ def new_theory(self): ref=(old["Qref"], old["nfref"]), ) new["heavy"] = { - "num_flavs_init": nf_default(old["Q0"] ** 2.0, default_atlas(ms, ks)) - if old["nf0"] is None - else old["nf0"], "matching_ratios": self.heavies("k%sThr", old), "masses_scheme": old["HQ"], } @@ -212,17 +209,20 @@ def new_operator(self): old_th = self.theory new = {} - new["mu0"] = old_th["Q0"] + ms = self.heavies("m%s", old_th) + ks = self.heavies("k%sThr", old_th) + new["init"] = ( + old_th["Q0"], + nf_default(old_th["Q0"] ** 2.0, default_atlas(ms, ks)) + if old_th["nf0"] is None + else old_th["nf0"], + ) if "mugrid" in old: mugrid = old["mugrid"] else: mu2grid = old["Q2grid"] if "Q2grid" in old else old["mu2grid"] mugrid = np.sqrt(mu2grid).tolist() - new["mugrid"] = flavored_mugrid( - mugrid, - list(self.heavies("m%s", old_th)), - list(self.heavies("k%sThr", old_th)), - ) + new["mugrid"] = flavored_mugrid(mugrid, list(ms), list(ks)) new["configs"] = {} evmod = old_th["ModEv"] diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index ce4679871..783e82f51 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -552,7 +552,7 @@ def build(self) -> EKO: self.access.open = True metadata = Metadata( _path=self.path, - origin=(self.operator.mu20, self.theory.heavy.num_flavs_init), + origin=(self.operator.init[0] ** 2, self.operator.init[1]), bases=Bases(xgrid=self.operator.xgrid), ) InternalPaths(self.path).bootstrap( diff --git a/src/eko/quantities/heavy_quarks.py b/src/eko/quantities/heavy_quarks.py index 3b081a03d..fe20fc53c 100644 --- a/src/eko/quantities/heavy_quarks.py +++ b/src/eko/quantities/heavy_quarks.py @@ -84,12 +84,6 @@ class HeavyInfo(DictLike): """ - num_flavs_init: FlavorsNumber - r"""Number of active flavors at fitting scale. - - I.e. :math:`n_{f,\text{ref}}(\mu^2_0)`, formerly called ``nf0``. - - """ masses: HeavyQuarkMasses """List of heavy quark masses.""" masses_scheme: QuarkMassScheme diff --git a/src/eko/runner/commons.py b/src/eko/runner/commons.py index c27b4c8a2..05a1d8dd3 100644 --- a/src/eko/runner/commons.py +++ b/src/eko/runner/commons.py @@ -32,7 +32,7 @@ def atlas(theory: TheoryCard, operator: OperatorCard) -> Atlas: # TODO: cache result masses = runcards.masses(theory, operator.configs.evolution_method) matching_scales = np.power(theory.heavy.matching_ratios, 2.0) * np.array(masses) - return Atlas(matching_scales.tolist(), (operator.mu20, theory.heavy.num_flavs_init)) + return Atlas(matching_scales.tolist(), (operator.mu20, operator.init[1])) def couplings(theory: TheoryCard, operator: OperatorCard) -> Couplings: diff --git a/src/ekobox/cards.py b/src/ekobox/cards.py index 3d4e346aa..d56e50da0 100644 --- a/src/ekobox/cards.py +++ b/src/ekobox/cards.py @@ -16,7 +16,6 @@ ref=(91.2, 5), ), heavy=dict( - num_flavs_init=4, masses=[ReferenceRunning([mq, nan]) for mq in (2.0, 4.5, 173.07)], masses_scheme="POLE", matching_ratios=[1.0, 1.0, 1.0], @@ -26,7 +25,7 @@ ) _operator = dict( - mu0=1.65, + init=(1.65, 4), mugrid=[(100.0, 5)], xgrid=np.geomspace(1e-7, 1.0, 50).tolist(), configs=dict( diff --git a/src/ekobox/cli/runcards.py b/src/ekobox/cli/runcards.py index 7fc46f1ef..c5511add5 100644 --- a/src/ekobox/cli/runcards.py +++ b/src/ekobox/cli/runcards.py @@ -35,7 +35,7 @@ def sub_example(destination: pathlib.Path): theory.order = (1, 0) cards.dump(theory.raw, path=destination / "theory.yaml") operator = cards.example.operator() - operator.mu0 = 1.65 + operator.init = (1.65, 4) operator.mugrid = [(np.sqrt(1e5), 5)] cards.dump(operator.raw, path=destination / "operator.yaml") _logger.info(f"Runcards generated to '{destination}'") diff --git a/src/ekobox/info_file.py b/src/ekobox/info_file.py index 35f2cfcae..3d4ca2634 100644 --- a/src/ekobox/info_file.py +++ b/src/ekobox/info_file.py @@ -35,7 +35,9 @@ def build( info file in lhapdf format """ template_info = copy.deepcopy(load.template_info) - template_info["SetDesc"] = "Evolved PDF from " + str(operators_card.mu0) + " GeV" + template_info["SetDesc"] = ( + "Evolved PDF from " + str(operators_card.init[0]) + " GeV" + ) template_info["Authors"] = "" template_info["FlavorScheme"] = "variable" template_info.update(info_update) diff --git a/src/ekobox/utils.py b/src/ekobox/utils.py index 095e605e9..4dc151e96 100644 --- a/src/ekobox/utils.py +++ b/src/ekobox/utils.py @@ -37,7 +37,7 @@ def ekos_product( # another kind of output which includes the theory and operator runcards) ep_match = eko_ini.approx( - (eko_fin.operator_card.mu0**2, eko_fin.theory_card.heavy.num_flavs_init), + (eko_fin.operator_card.init[0] ** 2, eko_fin.operator_card.init[1]), rtol=rtol, atol=atol, ) diff --git a/tests/eko/evolution_operator/test_grid.py b/tests/eko/evolution_operator/test_grid.py index 804388db6..01754578a 100644 --- a/tests/eko/evolution_operator/test_grid.py +++ b/tests/eko/evolution_operator/test_grid.py @@ -72,7 +72,7 @@ def test_mod_expanded(theory_card, theory_ffns, operator_card, tmp_path: pathlib else: theory = theory_card theory.order = (1, 0) - theory.heavy.num_flavs_init = nf0 + operator_card.init = (operator_card.init[0], nf0) path.unlink(missing_ok=True) opgrid = legacy.Runner(theory, operator_card, path=path).op_grid opg = opgrid.compute() diff --git a/tests/eko/io/test_manipulate.py b/tests/eko/io/test_manipulate.py index 3431d93ce..08b38e23d 100644 --- a/tests/eko/io/test_manipulate.py +++ b/tests/eko/io/test_manipulate.py @@ -213,7 +213,7 @@ def _test_to_all_evol( mu2_out = mu_out**2 nfout = 4 epout = (mu2_out, nfout) - eko_factory.operator.mu0 = float(np.sqrt(1.0)) + eko_factory.operator.init = (float(np.sqrt(1.0)), 3) eko_factory.operator.mugrid = [(mu_out, nfout)] eko_factory.operator.xgrid = xgrid eko_factory.operator.configs.interpolation_polynomial_degree = 1 diff --git a/tests/eko/test_quantities.py b/tests/eko/test_quantities.py index f9dcb9203..d3c412a25 100644 --- a/tests/eko/test_quantities.py +++ b/tests/eko/test_quantities.py @@ -33,7 +33,6 @@ def test_HeavyQuarks(): def test_HeavyInfo(): i = hq.HeavyInfo( - num_flavs_init=4, masses=hq.HeavyQuarkMasses( [ hq.QuarkMassRef([2.0, nan]), diff --git a/tests/ekobox/test_cards.py b/tests/ekobox/test_cards.py index 1a35e137e..00ef0e4c3 100644 --- a/tests/ekobox/test_cards.py +++ b/tests/ekobox/test_cards.py @@ -10,14 +10,14 @@ def test_generate_ocard(): mu0 = 1.65 mugrid = [(10.0, 6), (100.0, 5)] op = cards.example.operator() - op.mu0 = mu0 + op.init = (mu0, 4) op.mugrid = mugrid assert pytest.approx(op.mugrid) == mugrid assert pytest.approx(op.mu2grid) == np.array([mu**2 for mu, _ in mugrid]) assert op.configs.interpolation_polynomial_degree == 4 mugrid1 = [100.0, 5] op = cards.example.operator() - op.mu0 = mu0 + op.init = (mu0, 4) op.mugrid = mugrid1 op.configs.interpolation_polynomial_degree = 2 op.configs.interpolation_is_log = False @@ -35,7 +35,7 @@ def test_dump_load_op_card(tmp_path, cd): path1 = tmp_path / "debug_op.yaml" path2 = tmp_path / "debug_op_two.yaml" op = cards.example.operator() - op.mu0 = mu0 + op.init = (mu0, 4) cards.dump(op.raw, path1) cards.dump(op.raw, path2) op_loaded = cards.load(path1) @@ -52,7 +52,7 @@ def test_generate_theory_card(): assert theory.order[0] == 2 rawt = cards.example.raw_theory() assert isinstance(rawt, dict) - assert theory.heavy.num_flavs_init == rawt["heavy"]["num_flavs_init"] + assert theory.heavy.masses.c[0] == rawt["heavy"]["masses"][0][0] def containsnan(obj) -> bool: diff --git a/tests/ekobox/test_evol_pdf.py b/tests/ekobox/test_evol_pdf.py index 1c51dfdad..8e51c6e43 100644 --- a/tests/ekobox/test_evol_pdf.py +++ b/tests/ekobox/test_evol_pdf.py @@ -9,7 +9,7 @@ def init_cards(): op = cards.example.operator() - op.mu0 = 1.65 + op.init = (1.65, 4) op.xgrid = XGrid([0.1, 0.5, 1.0]) op.configs.interpolation_polynomial_degree = 1 theory = cards.example.theory() diff --git a/tests/ekobox/test_info_file.py b/tests/ekobox/test_info_file.py index 64af8eb93..ac50a2253 100644 --- a/tests/ekobox/test_info_file.py +++ b/tests/ekobox/test_info_file.py @@ -10,7 +10,7 @@ def test_build(): theory.order = (2, 0) theory.couplings.alphas = 0.2 op = cards.example.operator() - op.mu0 = 1.0 + op.init = (1.0, 3) op.mugrid = [(10.0, 5), (100.0, 5)] info = info_file.build( theory, op, 4, info_update={"SetDesc": "Prova", "NewArg": 15.3, "MTop": 1.0} diff --git a/tests/ekobox/test_utils.py b/tests/ekobox/test_utils.py index 557db679c..1233d1d91 100644 --- a/tests/ekobox/test_utils.py +++ b/tests/ekobox/test_utils.py @@ -16,10 +16,9 @@ def test_ekos_product(tmp_path): theory = cards.example.theory() theory.order = (1, 0) - theory.heavy.num_flavs_init = 5 op1 = cards.example.operator() - op1.mu0 = mu01 + op1.init = (mu01, 5) op1.mugrid = mugrid1 op1.xgrid = xgrid op1.configs.interpolation_polynomial_degree = 1 @@ -28,13 +27,13 @@ def test_ekos_product(tmp_path): mugrid2 = [(8.0, 5), (10.0, 5), (12.0, 5)] op2 = cards.example.operator() - op2.mu0 = mu0 + op2.init = (mu0, 5) op2.mugrid = mugrid2 op2.xgrid = xgrid op2.configs.interpolation_polynomial_degree = 1 op_err = copy.deepcopy(op2) - op_err.mu0 = mu01 + op_err.init = (mu01, 5) mu2first = (mugrid2[0][0] ** 2, mugrid2[0][1]) diff --git a/tests/ekomark/data/test_init.py b/tests/ekomark/data/test_init.py index 7d39dca43..278a06181 100644 --- a/tests/ekomark/data/test_init.py +++ b/tests/ekomark/data/test_init.py @@ -24,7 +24,7 @@ def test_runcards_opcard(): assert len(no.mu2grid) == len(no.evolgrid) assert no.evolgrid[0][-1] == 4 assert no.evolgrid[1][-1] == 5 - np.testing.assert_allclose(no.mu0, tc["Q0"]) + np.testing.assert_allclose(no.init[0], tc["Q0"]) np.testing.assert_allclose(no.mu20, tc["Q0"] ** 2.0) assert len(no.pids) == 14 check_dumpable(no) From 0d7a459d01b57fcbe34e0875f2e59a1d31373a76 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 16:00:20 +0200 Subject: [PATCH 30/67] Fix benchmark_APFEL_vfns_fact_to_ren --- benchmarks/eko/benchmark_strong_coupling.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmarks/eko/benchmark_strong_coupling.py b/benchmarks/eko/benchmark_strong_coupling.py index 1d1cd7219..d60bd28b0 100644 --- a/benchmarks/eko/benchmark_strong_coupling.py +++ b/benchmarks/eko/benchmark_strong_coupling.py @@ -334,7 +334,7 @@ def benchmark_APFEL_vfns_fact_to_ren(self): ] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 - nf_ref = 5 + nf_refs = (5, 6) fact_to_ren_lin_list = [0.567, 2.34] masses_list = np.power([2, 2 * 4, 2 * 92], 2) apfel_vals_dict_list = [ @@ -427,8 +427,8 @@ def benchmark_APFEL_vfns_fact_to_ren(self): ), }, ] - for fact_to_ren_lin, apfel_vals_dict in zip( - fact_to_ren_lin_list, apfel_vals_dict_list + for fact_to_ren_lin, apfel_vals_dict, nf_ref in zip( + fact_to_ren_lin_list, apfel_vals_dict_list, nf_refs ): # collect my values for order in [1, 2, 3]: From ba0a0cad21957dd112ee37c37adba2a50d59b486 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 16:22:42 +0200 Subject: [PATCH 31/67] Update notebooks --- doc/source/overview/tutorials/alpha_s.ipynb | 12 +- doc/source/overview/tutorials/dglap.ipynb | 15 +-- doc/source/overview/tutorials/output.ipynb | 8 +- doc/source/overview/tutorials/pdf.ipynb | 130 ++++++++++---------- 4 files changed, 78 insertions(+), 87 deletions(-) diff --git a/doc/source/overview/tutorials/alpha_s.ipynb b/doc/source/overview/tutorials/alpha_s.ipynb index 327eb39c9..f9cc5a240 100644 --- a/doc/source/overview/tutorials/alpha_s.ipynb +++ b/doc/source/overview/tutorials/alpha_s.ipynb @@ -39,12 +39,10 @@ "from eko.quantities.heavy_quarks import MatchingScales, QuarkMassScheme\n", "\n", "# set the (alpha_s, alpha_em) reference values\n", - "couplings_ref = CouplingsInfo(\n", - " alphas=0.118, alphaem=0.007496252, ref=(91.0, 5)\n", - ")\n", + "couplings_ref = CouplingsInfo(alphas=0.118, alphaem=0.007496252, ref=(91.0, 5))\n", "\n", "# set heavy quark masses and their threshold ratios\n", - "heavy_quark_masses = np.power([1.51, 4.92, 172.0],2)\n", + "heavy_quark_masses = np.power([1.51, 4.92, 172.0], 2)\n", "thresholds_ratios = np.array([1.0, 1.0, 1.0])\n", "\n", "# set (QCD,QED) perturbative order\n", @@ -88,9 +86,9 @@ } ], "source": [ - "target_scale = 10.0 ** 2\n", + "target_scale = 10.0**2\n", "a_s = sc.a_s(target_scale)\n", - "print(\"The value of alpha_s at Q^2=100 GeV^2 is: \", 4. * np.pi * a_s)" + "print(\"The value of alpha_s at Q^2=100 GeV^2 is: \", 4.0 * np.pi * a_s)" ] }, { @@ -106,7 +104,7 @@ ], "metadata": { "kernelspec": { - "display_name": "eko-KkPVjVhh-py3.10", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/doc/source/overview/tutorials/dglap.ipynb b/doc/source/overview/tutorials/dglap.ipynb index 0e271a00c..98cb4a6e1 100644 --- a/doc/source/overview/tutorials/dglap.ipynb +++ b/doc/source/overview/tutorials/dglap.ipynb @@ -68,7 +68,7 @@ "th_card = example.theory()\n", "op_card = example.operator()\n", "# here we replace the grid with a very minimal one, to speed up the example\n", - "op_card.xgrid = [1e-3, 1e-2, 1e-1, 5e-1, 1.]" + "op_card.xgrid = [1e-3, 1e-2, 1e-1, 5e-1, 1.0]" ] }, { @@ -91,14 +91,9 @@ "{'order': [1, 0],\n", " 'couplings': {'alphas': 0.118,\n", " 'alphaem': 0.007496252,\n", - " 'scale': 91.2,\n", - " 'max_num_flavs': 6,\n", - " 'num_flavs_ref': 5,\n", + " 'ref': [91.2, 5],\n", " 'em_running': False},\n", - " 'heavy': {'num_flavs_init': 4,\n", - " 'num_flavs_max_pdf': 6,\n", - " 'intrinsic_flavors': [4],\n", - " 'masses': [[2.0, nan], [4.5, nan], [173.07, nan]],\n", + " 'heavy': {'masses': [[2.0, nan], [4.5, nan], [173.07, nan]],\n", " 'masses_scheme': 'pole',\n", " 'matching_ratios': [1.0, 1.0, 1.0]},\n", " 'xif': 1.0,\n", @@ -123,7 +118,7 @@ { "data": { "text/plain": [ - "{'mu0': 1.65,\n", + "{'init': [1.65, 4],\n", " 'mugrid': [[100.0, 5]],\n", " 'xgrid': [0.001, 0.01, 0.1, 0.5, 1.0],\n", " 'configs': {'evolution_method': 'iterate-exact',\n", @@ -174,7 +169,7 @@ "id": "880aadcf-8f87-4918-a0bc-09581d0d3579", "metadata": {}, "source": [ - "The actual result is a complicate EKO object, we will discuss it in a separate tutorial.\n", + "The actual result is a complicate EKO object, which we will discuss it in a separate tutorial.\n", "\n", "You have just run your first DGLAP calculation!" ] diff --git a/doc/source/overview/tutorials/output.ipynb b/doc/source/overview/tutorials/output.ipynb index 47345ac35..1cfe9f071 100644 --- a/doc/source/overview/tutorials/output.ipynb +++ b/doc/source/overview/tutorials/output.ipynb @@ -34,7 +34,7 @@ "id": "2f8f0666-c6ab-40f6-86f5-15773f205b51", "metadata": {}, "source": [ - "We can access the operator, by using the `open` method (similar to python's `open`):" + "We can access the operator, by using the `read` method:" ] }, { @@ -76,8 +76,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "TheoryCard(order=(1, 0), couplings=CouplingsInfo(alphas=0.118, alphaem=0.007496252, scale=91.2, max_num_flavs=6, num_flavs_ref=5, em_running=False), heavy=HeavyInfo(num_flavs_init=4, num_flavs_max_pdf=6, intrinsic_flavors=[4, 5, 6], masses=[[2.0, nan], [4.5, nan], [173.07, nan]], masses_scheme=, matching_ratios=[1.0, 1.0, 1.0]), xif=1.0, n3lo_ad_variation=(0, 0, 0, 0))\n", - "OperatorCard(mu0=1.65, mugrid=[(100.0, 5)], xgrid=, configs=Configs(evolution_method=, ev_op_max_order=(10, 0), ev_op_iterations=10, scvar_method=None, inversion_method=None, interpolation_polynomial_degree=4, interpolation_is_log=True, polarized=False, time_like=False, n_integration_cores=0), debug=Debug(skip_singlet=False, skip_non_singlet=False), eko_version='0.0.0')\n" + "TheoryCard(order=(1, 0), couplings=CouplingsInfo(alphas=0.118, alphaem=0.007496252, ref=(91.2, 5), em_running=False), heavy=HeavyInfo(masses=[[2.0, nan], [4.5, nan], [173.07, nan]], masses_scheme=, matching_ratios=[1.0, 1.0, 1.0]), xif=1.0, n3lo_ad_variation=(0, 0, 0, 0))\n", + "OperatorCard(init=(1.65, 4), mugrid=[(100.0, 5)], xgrid=, configs=Configs(evolution_method=, ev_op_max_order=(10, 0), ev_op_iterations=10, scvar_method=None, inversion_method=None, interpolation_polynomial_degree=4, interpolation_is_log=True, polarized=False, time_like=False, n_integration_cores=0), debug=Debug(skip_singlet=False, skip_non_singlet=False), eko_version='0.0.0')\n" ] } ], @@ -143,7 +143,7 @@ ], "source": [ "with eko.EKO.read(\"./myeko.tar\") as evolution_operator:\n", - " with evolution_operator.operator((10000.,5)) as op:\n", + " with evolution_operator.operator((10000.0, 5)) as op:\n", " print(f\"operator: {op.operator.shape}\")\n", " print(f\"error: {op.error.shape}\")" ] diff --git a/doc/source/overview/tutorials/pdf.ipynb b/doc/source/overview/tutorials/pdf.ipynb index 923520f59..bfc6ad3ad 100644 --- a/doc/source/overview/tutorials/pdf.ipynb +++ b/doc/source/overview/tutorials/pdf.ipynb @@ -13,9 +13,9 @@ "id": "3e0dcd0f", "metadata": {}, "source": [ - "## Method 1: Using apply_pdf\n", + "## Method 1: Using `apply_pdf`\n", "\n", - "In this first part we will compute the eko and subsequently apply the initial PDF \"manually\" calling a dedicated function. " + "In this first part, we compute the eko and subsequently apply the initial PDF \"manually\" calling a dedicated function. " ] }, { @@ -52,6 +52,7 @@ "import pathlib\n", "import eko\n", "from banana import toy\n", + "\n", "pdf = toy.mkPDF(\"\", 0)" ] }, @@ -71,6 +72,7 @@ "outputs": [], "source": [ "from ekobox.apply import apply_pdf\n", + "\n", "with eko.EKO.read(\"./myeko.tar\") as evolution_operator:\n", " evolved_pdfs = apply_pdf(evolution_operator, pdf)" ] @@ -92,7 +94,7 @@ { "data": { "text/plain": [ - "dict_keys([10000.0])" + "dict_keys([(10000.0, 5)])" ] }, "execution_count": 3, @@ -134,7 +136,7 @@ } ], "source": [ - "evolved_pdfs[10000.0][\"pdfs\"][21]" + "evolved_pdfs[(10000.0, 5)][\"pdfs\"][21]" ] }, { @@ -150,7 +152,7 @@ "id": "e925d2c9", "metadata": {}, "source": [ - "## Method 2: Using evolve_pdfs\n", + "## Method 2: Using `evolve_pdfs`\n", "\n", "In this second part we illustrate how to get (and install) directly a LHAPDF set evolved with eko. " ] @@ -171,6 +173,7 @@ "outputs": [], "source": [ "from banana import toy\n", + "\n", "pdf = toy.mkPDF(\"\", 0)" ] }, @@ -195,10 +198,10 @@ "th_card = example.theory()\n", "op_card = example.operator()\n", "# here we replace the grid with a very minimal one, to speed up the example\n", - "op_card.xgrid = eko.interpolation.XGrid([1e-3, 1e-2, 1e-1, 5e-1, 1.])\n", - "op_card.mugrid = [(10.,5), (100.,5)]\n", + "op_card.xgrid = eko.interpolation.XGrid([1e-3, 1e-2, 1e-1, 5e-1, 1.0])\n", + "op_card.mugrid = [(10.0, 5), (100.0, 5)]\n", "# set QCD LO evolution\n", - "th_card.orders = (1,0)" + "th_card.orders = (1, 0)" ] }, { @@ -236,16 +239,10 @@ ], "source": [ "from ekobox.evol_pdf import evolve_pdfs\n", + "\n", "path = pathlib.Path(\"./myeko2.tar\")\n", "path.unlink(missing_ok=True)\n", - "evolve_pdfs(\n", - " [pdf],\n", - " th_card,\n", - " op_card,\n", - " install=True,\n", - " name=\"Evolved_PDF\",\n", - " store_path=path\n", - ")" + "evolve_pdfs([pdf], th_card, op_card, install=True, name=\"Evolved_PDF\", store_path=path)" ] }, { @@ -273,6 +270,7 @@ ], "source": [ "import lhapdf\n", + "\n", "evolved_pdf = lhapdf.mkPDF(\"Evolved_PDF\", 0)" ] }, @@ -300,12 +298,12 @@ } ], "source": [ - "pid = 21 # gluon pid\n", - "Q2 = 89.10 # Q^2 in Gev^2\n", - "x = 0.01 # momentum fraction \n", + "pid = 21 # gluon pid\n", + "Q2 = 89.10 # Q^2 in Gev^2\n", + "x = 0.01 # momentum fraction\n", "\n", "# check that the particle is present\n", - "print(\"has gluon?\",evolved_pdf.hasFlavor(pid))\n", + "print(\"has gluon?\", evolved_pdf.hasFlavor(pid))\n", "# now do the lookup\n", "xg = evolved_pdf.xfxQ2(pid, x, Q2)\n", "print(f\"xg(x={x}, Q2={Q2}) = {xg}\")" @@ -352,24 +350,28 @@ "import lhapdf\n", "from ekobox.cards import example\n", "from eko.interpolation import make_grid\n", - "from eko.quantities.heavy_quarks import QuarkMassRef,HeavyQuarks\n", + "from eko.quantities.heavy_quarks import QuarkMassRef, HeavyQuarks\n", "\n", "# get the PDF object\n", "ct14llo = lhapdf.mkPDF(\"CT14llo\")\n", "\n", "# setup the operator card\n", "op_card = example.operator()\n", - "op_card.xgrid = eko.interpolation.XGrid(make_grid(30, 30)) # x grid\n", - "op_card.mugrid = [(float(q),5) for q in np.geomspace(5., 100, 5)] # Q2 grid\n", - "op_card.init = (1.295000,3) # starting point for the evolution \n", + "op_card.xgrid = eko.interpolation.XGrid(make_grid(30, 30)) # x grid\n", + "op_card.mugrid = [(float(q), 5) for q in np.geomspace(5.0, 100, 5)] # Q2 grid\n", + "op_card.init = (1.295000, 3) # starting point for the evolution\n", "\n", "# setup the theory card - this can be mostly inferred from the PDF's .info file\n", - "\n", "th_card = example.theory()\n", - "th_card.orders = (1,0) # QCD LO\n", - "th_card.heavy.masses = HeavyQuarks([QuarkMassRef([1.3,nan]), QuarkMassRef([4.75,nan]), QuarkMassRef([172.,nan])]) # quark mass\n", - "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", - "th_card.couplings.ref = (91.1876,5) # the reference scale together with the number of flavors at which alpha_s is provided" + "th_card.orders = (1, 0) # QCD LO\n", + "th_card.heavy.masses = HeavyQuarks(\n", + " [QuarkMassRef([1.3, nan]), QuarkMassRef([4.75, nan]), QuarkMassRef([172.0, nan])]\n", + ") # quark mass\n", + "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", + "th_card.couplings.ref = (\n", + " 91.1876,\n", + " 5,\n", + ") # the reference scale together with the number of flavors at which alpha_s is provided" ] }, { @@ -403,15 +405,11 @@ ], "source": [ "from ekobox.evol_pdf import evolve_pdfs\n", + "\n", "path = pathlib.Path(\"./myeko_ct14llo.tar\")\n", "path.unlink(missing_ok=True)\n", "evolve_pdfs(\n", - " [ct14llo],\n", - " th_card,\n", - " op_card,\n", - " install=True,\n", - " name=\"my_ct14llo\",\n", - " store_path=path\n", + " [ct14llo], th_card, op_card, install=True, name=\"my_ct14llo\", store_path=path\n", ")" ] }, @@ -435,33 +433,33 @@ "output_type": "stream", "text": [ "LHAPDF 6.4.0 loading /home/felix/local/share/LHAPDF/my_ct14llo/my_ct14llo_0000.dat\n", + "my_ct14llo PDF set, member #0, version 1\n", " x Q2 ct14llo my_ct14llo relative_diff\n", - "0 0.000010 25.000000 7.635785e+01 7.630461e+01 0.000697\n", - "1 0.000173 25.000000 3.194273e+01 3.192092e+01 0.000683\n", - "2 0.003000 25.000000 1.081843e+01 1.081086e+01 0.000701\n", - "3 0.051962 25.000000 1.958956e+00 1.958632e+00 0.000166\n", - "4 0.900000 25.000000 1.922415e-05 1.955026e-05 -0.016963\n", - "5 0.000010 111.803399 1.333957e+02 1.332985e+02 0.000729\n", - "6 0.000173 111.803399 4.777286e+01 4.773664e+01 0.000758\n", - "7 0.003000 111.803399 1.341028e+01 1.339967e+01 0.000791\n", - "8 0.051962 111.803399 1.978216e+00 1.978130e+00 0.000044\n", - "9 0.900000 111.803399 6.644805e-06 6.753652e-06 -0.016381\n", - "10 0.000010 500.000000 1.967032e+02 1.965456e+02 0.000801\n", - "11 0.000173 500.000000 6.291393e+01 6.286095e+01 0.000842\n", - "12 0.003000 500.000000 1.542347e+01 1.540996e+01 0.000876\n", - "13 0.051962 500.000000 1.947465e+00 1.947391e+00 0.000038\n", - "14 0.900000 500.000000 2.929060e-06 2.977306e-06 -0.016471\n", - "15 0.000010 2236.067977 2.633266e+02 2.631109e+02 0.000819\n", - "16 0.000173 2236.067977 7.708540e+01 7.701938e+01 0.000856\n", - "17 0.003000 2236.067977 1.700410e+01 1.698928e+01 0.000872\n", - "18 0.051962 2236.067977 1.893923e+00 1.893971e+00 -0.000025\n", - "19 0.900000 2236.067977 1.544450e-06 1.570997e-06 -0.017189\n", - "20 0.000010 10000.000000 3.314097e+02 3.311351e+02 0.000829\n", - "21 0.000173 10000.000000 9.023010e+01 9.015279e+01 0.000857\n", - "22 0.003000 10000.000000 1.825934e+01 1.824402e+01 0.000839\n", - "23 0.051962 10000.000000 1.830992e+00 1.831183e+00 -0.000104\n", - "24 0.900000 10000.000000 9.288458e-07 9.447927e-07 -0.017169\n", - "my_ct14llo PDF set, member #0, version 1\n" + "0 0.000010 25.000000 7.635785e+01 7.630719e+01 0.000663\n", + "1 0.000173 25.000000 3.194273e+01 3.192239e+01 0.000637\n", + "2 0.003000 25.000000 1.081843e+01 1.081160e+01 0.000632\n", + "3 0.051962 25.000000 1.958956e+00 1.958820e+00 0.000069\n", + "4 0.900000 25.000000 1.922415e-05 1.955440e-05 -0.017179\n", + "5 0.000010 111.803399 1.333957e+02 1.333028e+02 0.000697\n", + "6 0.000173 111.803399 4.777286e+01 4.773855e+01 0.000718\n", + "7 0.003000 111.803399 1.341028e+01 1.340044e+01 0.000734\n", + "8 0.051962 111.803399 1.978216e+00 1.978292e+00 -0.000038\n", + "9 0.900000 111.803399 6.644805e-06 6.756354e-06 -0.016787\n", + "10 0.000010 500.000000 1.967032e+02 1.965517e+02 0.000770\n", + "11 0.000173 500.000000 6.291393e+01 6.286327e+01 0.000805\n", + "12 0.003000 500.000000 1.542347e+01 1.541073e+01 0.000826\n", + "13 0.051962 500.000000 1.947465e+00 1.947532e+00 -0.000034\n", + "14 0.900000 500.000000 2.929060e-06 2.979511e-06 -0.017224\n", + "15 0.000010 2236.067977 2.633266e+02 2.631189e+02 0.000789\n", + "16 0.000173 2236.067977 7.708540e+01 7.702204e+01 0.000822\n", + "17 0.003000 2236.067977 1.700410e+01 1.699004e+01 0.000827\n", + "18 0.051962 2236.067977 1.893923e+00 1.894094e+00 -0.000090\n", + "19 0.900000 2236.067977 1.544450e-06 1.572860e-06 -0.018395\n", + "20 0.000010 10000.000000 3.314097e+02 3.311450e+02 0.000799\n", + "21 0.000173 10000.000000 9.023010e+01 9.015576e+01 0.000824\n", + "22 0.003000 10000.000000 1.825934e+01 1.824477e+01 0.000798\n", + "23 0.051962 10000.000000 1.830992e+00 1.831291e+00 -0.000163\n", + "24 0.900000 10000.000000 9.288458e-07 9.463689e-07 -0.018866\n" ] } ], @@ -471,15 +469,15 @@ "# load evolved pdf\n", "my_ct14llo = lhapdf.mkPDF(\"my_ct14llo\", 0)\n", "\n", - "pid = 21 # gluon pid\n", + "pid = 21 # gluon pid\n", "\n", "# collect data\n", - "log = {\"x\": [], \"Q2\" : [], \"ct14llo\": [], \"my_ct14llo\": [], \"relative_diff\": []} \n", - "for q in np.geomspace(5., 100, 5):\n", - " q2 = q**2.\n", + "log = {\"x\": [], \"Q2\": [], \"ct14llo\": [], \"my_ct14llo\": [], \"relative_diff\": []}\n", + "for q in np.geomspace(5.0, 100, 5):\n", + " q2 = q**2.0\n", " for x in np.geomspace(1e-5, 0.9, 5):\n", " value = ct14llo.xfxQ2(pid, x, q2)\n", - " my_value = my_ct14llo.xfxQ2(pid, x, q2)\n", + " my_value = my_ct14llo.xfxQ2(pid, x, q2)\n", " log[\"x\"].append(x)\n", " log[\"Q2\"].append(q2)\n", " log[\"ct14llo\"].append(value)\n", From 3e2d12a4ff0a1013ce33cd07b193a2c52c9e4939 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 17:06:34 +0200 Subject: [PATCH 32/67] Drop Bases --- src/eko/io/bases.py | 117 ---------------------------------- src/eko/io/metadata.py | 8 +-- src/eko/io/struct.py | 12 +--- src/ekobox/apply.py | 12 ++-- tests/eko/io/test_bases.py | 83 ------------------------ tests/eko/io/test_metadata.py | 6 +- tests/eko/io/test_runcards.py | 1 - tests/eko/runner/__init__.py | 10 +-- tests/eko/runner/conftest.py | 3 +- tests/ekobox/test_apply.py | 11 ++-- 10 files changed, 27 insertions(+), 236 deletions(-) delete mode 100644 src/eko/io/bases.py delete mode 100644 tests/eko/io/test_bases.py diff --git a/src/eko/io/bases.py b/src/eko/io/bases.py deleted file mode 100644 index 97a28dc36..000000000 --- a/src/eko/io/bases.py +++ /dev/null @@ -1,117 +0,0 @@ -"""Operators bases.""" -from dataclasses import dataclass, fields -from typing import Optional - -import numpy as np -import numpy.typing as npt - -from .. import basis_rotation as br -from .. import interpolation -from .dictlike import DictLike - - -@dataclass -class Bases(DictLike): - """Rotations related configurations. - - Here "Rotation" is intended in a broad sense: it includes both rotations in - flavor space (labeled with suffix `pids`) and in :math:`x`-space (labeled - with suffix `grid`). - Rotations in :math:`x`-space correspond to reinterpolate the result on a - different basis of polynomials. - - """ - - xgrid: interpolation.XGrid - """Internal momentum fraction grid.""" - _targetgrid: Optional[interpolation.XGrid] = None - _inputgrid: Optional[interpolation.XGrid] = None - _targetpids: Optional[npt.NDArray] = None - _inputpids: Optional[npt.NDArray] = None - - def __post_init__(self): - """Adjust types when loaded from serialized object.""" - for attr in ("xgrid", "_inputgrid", "_targetgrid"): - value = getattr(self, attr) - if value is None: - continue - if isinstance(value, (np.ndarray, list)): - setattr(self, attr, interpolation.XGrid(value)) - elif not isinstance(value, interpolation.XGrid): - setattr(self, attr, interpolation.XGrid.load(value)) - - @property - def pids(self): - """Internal flavor basis, used for computation.""" - return np.array(br.flavor_basis_pids) - - @property - def inputpids(self) -> npt.NDArray: - """Provide pids expected on the input PDF.""" - if self._inputpids is None: - return self.pids - return self._inputpids - - @inputpids.setter - def inputpids(self, value): - self._inputpids = value - - @property - def targetpids(self) -> npt.NDArray: - """Provide pids corresponding to the output PDF.""" - if self._targetpids is None: - return self.pids - return self._targetpids - - @targetpids.setter - def targetpids(self, value): - self._targetpids = value - - @property - def inputgrid(self) -> interpolation.XGrid: - """Provide :math:`x`-grid expected on the input PDF.""" - if self._inputgrid is None: - return self.xgrid - return self._inputgrid - - @inputgrid.setter - def inputgrid(self, value: interpolation.XGrid): - self._inputgrid = value - - @property - def targetgrid(self) -> interpolation.XGrid: - """Provide :math:`x`-grid corresponding to the output PDF.""" - if self._targetgrid is None: - return self.xgrid - return self._targetgrid - - @targetgrid.setter - def targetgrid(self, value: interpolation.XGrid): - self._targetgrid = value - - @classmethod - def from_dict(cls, dictionary: dict): - """Deserialize rotation. - - Load from full state, but with public names. - - """ - d = dictionary.copy() - for f in fields(cls): - if f.name.startswith("_"): - d[f.name] = d.pop(f.name[1:]) - return cls._from_dict(d) - - @property - def raw(self): - """Serialize rotation. - - Pass through interfaces, access internal values but with a public name. - - """ - d = self._raw() - for key in d.copy(): - if key.startswith("_"): - d[key[1:]] = d.pop(key) - - return d diff --git a/src/eko/io/metadata.py b/src/eko/io/metadata.py index 415b2dfa5..00f189ab4 100644 --- a/src/eko/io/metadata.py +++ b/src/eko/io/metadata.py @@ -8,7 +8,7 @@ import yaml from .. import version as vmod -from .bases import Bases +from ..interpolation import XGrid from .dictlike import DictLike from .paths import InternalPaths from .types import EvolutionPoint as EPoint @@ -34,10 +34,8 @@ class Metadata(DictLike): origin: EPoint """Inital scale.""" - bases: Bases - """Manipulation information, describing the current status of the EKO (e.g. - `inputgrid` and `targetgrid`). - """ + xgrid: XGrid + """Interpolation grid""" # tagging information _path: Optional[pathlib.Path] = None """Path to temporary dir.""" diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index fecba3c57..dbbb231f9 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -16,7 +16,6 @@ from .. import interpolation from . import exceptions, raw from .access import AccessConfigs -from .bases import Bases from .inventory import Inventory from .items import Evolution, Matching, Operator, Recipe, Target from .metadata import Metadata @@ -105,20 +104,15 @@ def paths(self) -> InternalPaths: """Accessor for internal paths.""" return InternalPaths(self.metadata.path) - @property - def bases(self) -> Bases: - """Bases information.""" - return self.metadata.bases - @property def xgrid(self) -> interpolation.XGrid: """Momentum fraction internal grid.""" - return self.bases.xgrid + return self.metadata.xgrid @xgrid.setter def xgrid(self, value: interpolation.XGrid): """Set `xgrid` value.""" - self.bases.xgrid = value + self.metadata.xgrid = value self.update() @property @@ -551,7 +545,7 @@ def build(self) -> EKO: metadata = Metadata( _path=self.path, origin=(self.operator.mu20, self.theory.heavy.num_flavs_init), - bases=Bases(xgrid=self.operator.xgrid), + xgrid=self.operator.xgrid, ) InternalPaths(self.path).bootstrap( theory=self.theory.raw, diff --git a/src/ekobox/apply.py b/src/ekobox/apply.py index c392ffe78..5722a6ad6 100644 --- a/src/ekobox/apply.py +++ b/src/ekobox/apply.py @@ -74,12 +74,12 @@ def apply_pdf_flavor( output PDFs and their associated errors for the computed mu2grid """ # create pdfs - pdfs = np.zeros((len(eko.bases.inputpids), len(eko.bases.inputgrid))) - for j, pid in enumerate(eko.bases.inputpids): + pdfs = np.zeros((len(br.flavor_basis_pids), len(eko.xgrid))) + for j, pid in enumerate(br.flavor_basis_pids): if not lhapdf_like.hasFlavor(pid): continue pdfs[j] = np.array( - [lhapdf_like.xfxQ2(pid, x, eko.mu20) / x for x in eko.bases.inputgrid.raw] + [lhapdf_like.xfxQ2(pid, x, eko.mu20) / x for x in eko.xgrid.raw] ) # build output @@ -91,11 +91,11 @@ def apply_pdf_flavor( else: error_final = None out_grid[ep] = { - "pdfs": dict(zip(eko.bases.targetpids, pdf_final)), + "pdfs": dict(zip(br.flavor_basis_pids, pdf_final)), "errors": None, } if error_final is not None: - out_grid[ep]["errors"] = dict(zip(eko.bases.targetpids, error_final)) + out_grid[ep]["errors"] = dict(zip(br.flavor_basis_pids, error_final)) # rotate to evolution basis if flavor_rotation is not None: @@ -117,7 +117,7 @@ def apply_pdf_flavor( # rotate/interpolate to target grid if targetgrid is not None: b = interpolation.InterpolatorDispatcher( - xgrid=eko.bases.targetgrid, + xgrid=eko.xgrid, polynomial_degree=eko.operator_card.configs.interpolation_polynomial_degree, mode_N=False, ) diff --git a/tests/eko/io/test_bases.py b/tests/eko/io/test_bases.py deleted file mode 100644 index a0165243f..000000000 --- a/tests/eko/io/test_bases.py +++ /dev/null @@ -1,83 +0,0 @@ -from dataclasses import fields - -import numpy as np - -from eko import basis_rotation as br -from eko import interpolation -from eko.io.bases import Bases - - -class TestBases: - XGRID_TEST = [1e-3, 1e-2, 1e-1, 1.0] - - def test_serialization(self): - rot = Bases(interpolation.XGrid(self.XGRID_TEST)) - - d = rot.raw - rot1 = rot.from_dict(d) - - for f in fields(Bases): - assert getattr(rot, f.name) == getattr(rot1, f.name) - - assert d["targetgrid"] is None - assert "_targetgrid" not in d - - def test_pids(self): - rot = Bases(interpolation.XGrid(self.XGRID_TEST)) - - # no check on correctness of value set - rot.inputpids = [0, 1] - # but the internal grid is unmodified - assert len(rot.pids) == 14 - # and fallback implemented for unset external bases - assert np.all(rot.targetpids == rot.pids) - - def test_grids(self): - rot = Bases(interpolation.XGrid(self.XGRID_TEST)) - - # no check on correctness of value set - rot.inputgrid = interpolation.XGrid([0.1, 1]) - # but the internal grid is unmodified - assert len(rot.xgrid) == len(self.XGRID_TEST) - # and fallback implemented for unset external grids - assert np.all(rot.targetgrid == rot.xgrid) - - def test_fallback(self): - xg = interpolation.XGrid([0.1, 1.0]) - r = Bases(xgrid=xg) - np.testing.assert_allclose(r.targetpids, r.pids) - np.testing.assert_allclose(r.inputpids, r.pids) - assert r.xgrid == xg - assert r.targetgrid == xg - assert r.inputgrid == xg - - def test_overwrite(self): - tpids = np.array([3, 4] + list(br.flavor_basis_pids[2:])) - ipids = np.array([5, 6] + list(br.flavor_basis_pids[2:])) - xg = interpolation.XGrid([0.1, 1.0]) - txg = interpolation.XGrid([0.2, 1.0]) - ixg = interpolation.XGrid([0.3, 1.0]) - r = Bases( - xgrid=xg, - _targetgrid=txg, - _inputgrid=ixg, - _targetpids=tpids, - _inputpids=ipids, - ) - np.testing.assert_allclose(r.targetpids, tpids) - np.testing.assert_allclose(r.inputpids, ipids) - assert r.xgrid == xg - assert r.targetgrid == txg - assert r.inputgrid == ixg - - def test_init(self): - xg = interpolation.XGrid([0.1, 1.0]) - txg = np.array([0.2, 1.0]) - ixg = {"grid": [0.3, 1.0], "log": True} - r = Bases(xgrid=xg, _targetgrid=txg, _inputgrid=ixg) - assert isinstance(r.xgrid, interpolation.XGrid) - assert isinstance(r.targetgrid, interpolation.XGrid) - assert isinstance(r.inputgrid, interpolation.XGrid) - assert r.xgrid == xg - assert r.targetgrid == interpolation.XGrid(txg) - assert r.inputgrid == interpolation.XGrid.load(ixg) diff --git a/tests/eko/io/test_metadata.py b/tests/eko/io/test_metadata.py index a5651e0c8..fcfa8dd09 100644 --- a/tests/eko/io/test_metadata.py +++ b/tests/eko/io/test_metadata.py @@ -3,11 +3,11 @@ import pytest import yaml -from eko.io import bases, metadata, paths +from eko.io import metadata, paths def test_metadata(tmp_path, caplog): - m = metadata.Metadata((1.0, 3), bases.Bases([0.1, 1.0])) + m = metadata.Metadata(origin=(1.0, 3), xgrid=[0.1, 1.0]) # errors with caplog.at_level(logging.INFO): m.update() @@ -26,7 +26,7 @@ def test_metadata(tmp_path, caplog): m.version = "0.0.0-a1~really1.0.0" m.update() # if I read back the thing should be what I set - mn = metadata.Metadata((1.0, 3), bases.Bases([0.1, 1.0])) + mn = metadata.Metadata(origin=(1.0, 3), xgrid=[0.1, 1.0]) mm = metadata.Metadata.load(tmp_path) assert m.path == tmp_path assert mm.version != mn.version diff --git a/tests/eko/io/test_runcards.py b/tests/eko/io/test_runcards.py index 6af37edcb..4b4996336 100644 --- a/tests/eko/io/test_runcards.py +++ b/tests/eko/io/test_runcards.py @@ -7,7 +7,6 @@ from banana.data.theories import default_card as theory_card from eko.io import runcards as rc -from eko.io.bases import Bases from ekomark.data.operators import default_card as operator_card diff --git a/tests/eko/runner/__init__.py b/tests/eko/runner/__init__.py index c8ec5b854..0e3ea68c0 100644 --- a/tests/eko/runner/__init__.py +++ b/tests/eko/runner/__init__.py @@ -1,19 +1,21 @@ import numpy as np +from eko import basis_rotation as br + def check_shapes(o, txs, ixs, theory_card, operators_card): - tpids = len(o.bases.targetpids) - ipids = len(o.bases.inputpids) + tpids = len(br.flavor_basis_pids) + ipids = len(br.flavor_basis_pids) op_shape = (tpids, len(txs), ipids, len(ixs)) # check output = input np.testing.assert_allclose(o.xgrid.raw, operators_card.xgrid.raw) # targetgrid and inputgrid in the opcard are now ignored, we are testing this np.testing.assert_allclose( - o.bases.targetgrid.raw, + o.xgrid.raw, txs.raw, ) - np.testing.assert_allclose(o.bases.inputgrid.raw, ixs.raw) + np.testing.assert_allclose(o.xgrid.raw, ixs.raw) np.testing.assert_allclose(o.mu20, operators_card.mu20) # check available operators ~o.operators diff --git a/tests/eko/runner/conftest.py b/tests/eko/runner/conftest.py index a1516b2a7..a2966c5e9 100644 --- a/tests/eko/runner/conftest.py +++ b/tests/eko/runner/conftest.py @@ -4,6 +4,7 @@ import pytest from eko import EKO +from eko import basis_rotation as br from eko.io.items import Operator from eko.io.runcards import OperatorCard, TheoryCard from eko.runner import commons, recipes @@ -21,7 +22,7 @@ def neweko(theory_card: TheoryCard, operator_card: OperatorCard, tmp_path: Path) @pytest.fixture def identity(neweko: EKO): xs = len(neweko.xgrid.raw) - flavs = len(neweko.bases.pids) + flavs = len(br.flavor_basis_pids) return Operator(operator=np.eye(xs * flavs).reshape((xs, flavs, xs, flavs))) diff --git a/tests/ekobox/test_apply.py b/tests/ekobox/test_apply.py index 8fa23548f..70eb74adc 100644 --- a/tests/ekobox/test_apply.py +++ b/tests/ekobox/test_apply.py @@ -1,5 +1,6 @@ import numpy as np +from eko import basis_rotation as br from ekobox import apply from tests.conftest import EKOFactory @@ -12,13 +13,13 @@ def test_apply(self, eko_factory: EKOFactory, fake_pdf): pdf_grid = apply.apply_pdf(eko, fake_pdf) assert len(pdf_grid) == len(eko.evolgrid) pdfs = pdf_grid[ep_out]["pdfs"] - assert list(pdfs.keys()) == list(eko.bases.targetpids) + assert list(pdfs.keys()) == list(br.flavor_basis_pids) # rotate to target_grid target_grid = [0.75] pdf_grid = apply.apply_pdf(eko, fake_pdf, target_grid) assert len(pdf_grid) == 1 pdfs = pdf_grid[ep_out]["pdfs"] - assert list(pdfs.keys()) == list(eko.bases.targetpids) + assert list(pdfs.keys()) == list(br.flavor_basis_pids) def test_apply_flavor(self, eko_factory: EKOFactory, fake_pdf, monkeypatch): eko = eko_factory.get() @@ -27,12 +28,8 @@ def test_apply_flavor(self, eko_factory: EKOFactory, fake_pdf, monkeypatch): monkeypatch.setattr( "eko.basis_rotation.rotate_flavor_to_evolution", np.ones((14, 14)) ) - monkeypatch.setattr( - "eko.basis_rotation.flavor_basis_pids", - eko.bases.targetpids, - ) fake_evol_basis = tuple( - ["a", "b"] + [str(x) for x in range(len(eko.bases.pids) - 2)] + ["a", "b"] + [str(x) for x in range(len(br.flavor_basis_pids) - 2)] ) monkeypatch.setattr("eko.basis_rotation.evol_basis", fake_evol_basis) pdf_grid = apply.apply_pdf(eko, fake_pdf, rotate_to_evolution_basis=True) From 7cf9e1b30d2f17553094e23db15775aabc8e9545 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 1 Aug 2023 17:57:50 +0200 Subject: [PATCH 33/67] Use correct types in LHA --- benchmarks/lha_paper_bench.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/benchmarks/lha_paper_bench.py b/benchmarks/lha_paper_bench.py index 9254307dc..f92755af9 100644 --- a/benchmarks/lha_paper_bench.py +++ b/benchmarks/lha_paper_bench.py @@ -12,19 +12,15 @@ register(__file__) +_sqrt2 = float(np.sqrt(2.0)) + base_theory = { "ModEv": "EXA", - "Q0": np.sqrt( - 2.0 - ), # Eq. (30) :cite:`Giele:2002hx`, Eq. (4.53) :cite:`Dittmar:2005ed` - "mc": np.sqrt( - 2.0 - ), # Eq. (34) :cite:`Giele:2002hx`, Eq. (4.56) :cite:`Dittmar:2005ed` + "Q0": _sqrt2, # Eq. (30) :cite:`Giele:2002hx`, Eq. (4.53) :cite:`Dittmar:2005ed` + "mc": _sqrt2, # Eq. (34) :cite:`Giele:2002hx`, Eq. (4.56) :cite:`Dittmar:2005ed` "mb": 4.5, "mt": 175, - "Qref": np.sqrt( - 2.0 - ), # Eq. (32) :cite:`Giele:2002hx`,Eq. (4.53) :cite:`Dittmar:2005ed` + "Qref": _sqrt2, # Eq. (32) :cite:`Giele:2002hx`,Eq. (4.53) :cite:`Dittmar:2005ed` "alphas": 0.35, # Eq. (4.55) :cite:`Dittmar:2005ed` "alphaqed": 0.007496, "QED": 0, @@ -78,11 +74,11 @@ def sv_theories(self, pto): """ low = self.theory.copy() low["PTO"] = pto - low["XIF"] = np.sqrt(1.0 / 2.0) + low["XIF"] = 1.0 / _sqrt2 low["ModSV"] = "exponentiated" high = self.theory.copy() high["PTO"] = pto - high["XIF"] = np.sqrt(2.0) + high["XIF"] = _sqrt2 high["ModSV"] = "exponentiated" return [high, low] @@ -301,7 +297,7 @@ def benchmark_sv(self, pto): sv_theory["kcThr"] = 1.0 + 1e-15 sv_theory["nfref"] = 4 sv_theory["EScaleVar"] = 0 - low["XIR"] = np.sqrt(2.0) - high["XIR"] = np.sqrt(0.5) + low["XIR"] = _sqrt2 + high["XIR"] = 1.0 / _sqrt2 self.run_lha([low, high]) From 50cd3aff60e7cd67ae7d7b3fbfff1ae0919ba329 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Wed, 16 Aug 2023 16:01:34 +0200 Subject: [PATCH 34/67] Dismiss PathLike internal usage in struct --- src/eko/io/struct.py | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index fecba3c57..7acd6af5e 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -2,12 +2,11 @@ import contextlib import copy import logging -import os -import pathlib import shutil import tarfile import tempfile from dataclasses import dataclass +from pathlib import Path from typing import List, Optional import numpy as np @@ -30,7 +29,7 @@ TEMP_PREFIX = "eko-" -def inventories(path: pathlib.Path, access: AccessConfigs) -> dict: +def inventories(path: Path, access: AccessConfigs) -> dict: """Set up empty inventories for object initialization.""" paths = InternalPaths(path) return dict( @@ -293,7 +292,7 @@ def unload(self): # operator management # ------------------- - def deepcopy(self, path: os.PathLike): + def deepcopy(self, path: Path): """Create a deep copy of current instance. The managed on-disk object is copied as well, to the new ``path`` @@ -327,11 +326,11 @@ def deepcopy(self, path: os.PathLike): self.unload() new = copy.deepcopy(self) - new.access.path = pathlib.Path(path) + new.access.path = path new.access.readonly = False new.access.open = True - tmpdir = pathlib.Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) + tmpdir = Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) new.metadata.path = tmpdir # copy old dir to new dir tmpdir.rmdir() @@ -339,17 +338,8 @@ def deepcopy(self, path: os.PathLike): new.close() @staticmethod - def load(tarpath: os.PathLike, dest: os.PathLike): - """Load the content of archive in a target directory. - - Parameters - ---------- - tarpath: os.PathLike - the archive to extract - tmppath: os.PathLike - the destination directory - - """ + def load(tarpath: Path, dest: Path): + """Load the content of archive in a target directory.""" try: with tarfile.open(tarpath) as tar: raw.safe_extractall(tar, dest) @@ -357,9 +347,8 @@ def load(tarpath: os.PathLike, dest: os.PathLike): raise exceptions.OutputNotTar(f"Not a valid tar archive: '{tarpath}'") @classmethod - def open(cls, path: os.PathLike, mode="r"): + def open(cls, path: Path, mode: str = "r"): """Open EKO object in the specified mode.""" - path = pathlib.Path(path) access = AccessConfigs(path, readonly=False, open=True) load = False if mode == "r": @@ -372,7 +361,7 @@ def open(cls, path: os.PathLike, mode="r"): else: raise ValueError(f"Unknown file mode: {mode}") - tmpdir = pathlib.Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) + tmpdir = Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) if load: cls.load(path, tmpdir) metadata = Metadata.load(tmpdir) @@ -388,7 +377,7 @@ def open(cls, path: os.PathLike, mode="r"): return opened @classmethod - def read(cls, path: os.PathLike): + def read(cls, path: Path): """Read the content of an EKO. Type-safe alias for:: @@ -401,7 +390,7 @@ def read(cls, path: os.PathLike): return eko @classmethod - def create(cls, path: os.PathLike): + def create(cls, path: Path): """Create a new EKO. Type-safe alias for:: @@ -414,7 +403,7 @@ def create(cls, path: os.PathLike): return builder @classmethod - def edit(cls, path: os.PathLike): + def edit(cls, path: Path): """Read from and write on existing EKO. Type-safe alias for:: @@ -430,12 +419,12 @@ def __enter__(self): """Allow EKO to be used in :obj:`with` statements.""" return self - def dump(self, archive: Optional[os.PathLike] = None): + def dump(self, archive: Optional[Path] = None): """Dump the current content to archive. Parameters ---------- - archive: os.PathLike or None + archive: Path or None path to archive, in general you should keep the default, that will make use of the registered path (default: ``None``) @@ -494,7 +483,7 @@ def raw(self) -> dict: class Builder: """Build EKO instances.""" - path: pathlib.Path + path: Path """Path on disk to .""" access: AccessConfigs """Access related configurations.""" From 3e1c57f3c28f8bbba25ee3b0fac901a67fd06613 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Wed, 16 Aug 2023 17:26:50 +0200 Subject: [PATCH 35/67] Add test for open loading --- tests/eko/io/test_struct.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/eko/io/test_struct.py b/tests/eko/io/test_struct.py index b7ff9877b..399018ddd 100644 --- a/tests/eko/io/test_struct.py +++ b/tests/eko/io/test_struct.py @@ -28,7 +28,7 @@ def test_new_error(self, tmp_path: pathlib.Path, theory_card, operator_card): for args in [(None, None), (theory_card, None), (None, operator_card)]: with pytest.raises(RuntimeError, match="missing"): with struct.EKO.create(tmp_path / "Blub2.tar") as builder: - eko = builder.load_cards(*args).build() + _ = builder.load_cards(*args).build() def test_load_error(self, tmp_path): # try to read from a non-tar path @@ -184,3 +184,16 @@ def test_context_operator(self, eko_factory: EKOFactory): assert isinstance(op, struct.Operator) assert eko.operators.cache[Target.from_ep(ep)] is None + + def test_load_opened(self, tmp_path: pathlib.Path, eko_factory: EKOFactory): + """Test the loading of an already opened EKO.""" + eko = eko_factory.get() + eko.close() + # drop from cache to avoid double close by the fixture + eko_factory.cache = None + + assert eko.access.path is not None + read_closed = EKO.read(eko.access.path, dest=tmp_path) + read_opened = EKO.read(tmp_path, extract=False) + + assert read_closed.metadata == read_opened.metadata From 44e6a3867bc101e12abd1425970b9a9cbc987e84 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Wed, 16 Aug 2023 17:27:02 +0200 Subject: [PATCH 36/67] Implement open loading The struct methods have been rearranged, to avoid increasing too much the complexity, in particular for no special purpose --- src/eko/io/access.py | 2 +- src/eko/io/metadata.py | 2 +- src/eko/io/struct.py | 109 +++++++++++++++++++++-------------------- 3 files changed, 59 insertions(+), 54 deletions(-) diff --git a/src/eko/io/access.py b/src/eko/io/access.py index b8dec50a8..5a4d631c0 100644 --- a/src/eko/io/access.py +++ b/src/eko/io/access.py @@ -43,7 +43,7 @@ class ClosedOperator(RuntimeError, exceptions.OutputError): class AccessConfigs: """Configurations specified during opening of an EKO.""" - path: Path + path: Optional[Path] """The path to the permanent object.""" readonly: bool "Read-only flag" diff --git a/src/eko/io/metadata.py b/src/eko/io/metadata.py index 415b2dfa5..857f03b25 100644 --- a/src/eko/io/metadata.py +++ b/src/eko/io/metadata.py @@ -40,7 +40,7 @@ class Metadata(DictLike): """ # tagging information _path: Optional[pathlib.Path] = None - """Path to temporary dir.""" + """Path to the open dir.""" version: str = vmod.__version__ """Library version used to create the corresponding file.""" data_version: int = vmod.__data_version__ diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index 7acd6af5e..c2e1daba7 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -338,8 +338,8 @@ def deepcopy(self, path: Path): new.close() @staticmethod - def load(tarpath: Path, dest: Path): - """Load the content of archive in a target directory.""" + def extract(tarpath: Path, dest: Path): + """Extract the content of archive in a target directory.""" try: with tarfile.open(tarpath) as tar: raw.safe_extractall(tar, dest) @@ -347,73 +347,77 @@ def load(tarpath: Path, dest: Path): raise exceptions.OutputNotTar(f"Not a valid tar archive: '{tarpath}'") @classmethod - def open(cls, path: Path, mode: str = "r"): - """Open EKO object in the specified mode.""" - access = AccessConfigs(path, readonly=False, open=True) - load = False - if mode == "r": - load = True - access.readonly = True - elif mode in "w": - pass - elif mode in "a": - load = True - else: - raise ValueError(f"Unknown file mode: {mode}") + def load(cls, path: Path): + """Load the EKO from disk information. - tmpdir = Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) - if load: - cls.load(path, tmpdir) - metadata = Metadata.load(tmpdir) - opened = cls( - **inventories(tmpdir, access), - metadata=metadata, - access=access, - ) - opened.operators.sync() - else: - opened = Builder(path=tmpdir, access=access) + Note + ---- + No archive path is assigned to the :cls:`EKO` object, setting its + :attr:`EKO.access.path` to `None`. + If you want to properly load from an archive, use the :meth:`read` + constructor. + + """ + access = AccessConfigs(None, readonly=True, open=True) + + metadata = Metadata.load(path) + loaded = cls( + **inventories(path, access), + metadata=metadata, + access=access, + ) + loaded.operators.sync() - return opened + return loaded @classmethod - def read(cls, path: Path): - """Read the content of an EKO. + def read( + cls, + path: Path, + extract: bool = True, + dest: Optional[Path] = None, + readonly: bool = False, + ): + """Load an existing EKO. + + If the `extract` attribute is `True` the EKO is loaded from its archived + format. Otherwise, the `path` is interpreted as the location of an + already extracted folder. - Type-safe alias for:: - EKO.open(... , "r") """ - eko = cls.open(path, "r") - assert isinstance(eko, EKO) - return eko + if extract: + dir_ = Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) if dest is None else dest + cls.extract(path, dir_) + else: + dir_ = path - @classmethod - def create(cls, path: Path): - """Create a new EKO. + loaded = cls.load(dir_) - Type-safe alias for:: + loaded.access.readonly = readonly + if extract: + loaded.access.path = path - EKO.open(... , "w") + return loaded - """ - builder = cls.open(path, "w") - assert isinstance(builder, Builder) + @classmethod + def create(cls, path: Path): + """Create a new EKO.""" + access = AccessConfigs(path, readonly=False, open=True) + builder = Builder( + path=Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)), access=access + ) return builder @classmethod - def edit(cls, path: Path): + def edit(cls, *args, **kwargs): """Read from and write on existing EKO. - Type-safe alias for:: - - EKO.open(... , "a") + Alias of `EKO.read(..., readonly=False)`, see :meth:`read`. """ - eko = cls.open(path, "a") - assert isinstance(eko, EKO) - return eko + return cls.read(*args, readonly=False, **kwargs) def __enter__(self): """Allow EKO to be used in :obj:`with` statements.""" @@ -463,7 +467,8 @@ def __exit__(self, exc_type: type, _exc_value, _traceback): if exc_type is not None: return - self.close() + if self.access.path is not None: + self.close() @property def raw(self) -> dict: @@ -484,7 +489,7 @@ class Builder: """Build EKO instances.""" path: Path - """Path on disk to .""" + """Path on disk to the EKO.""" access: AccessConfigs """Access related configurations.""" From cb58d8db1f0881b1444d9bc92d55b9927fb86e9c Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Wed, 16 Aug 2023 17:30:32 +0200 Subject: [PATCH 37/67] Switch read-only default --- src/eko/io/struct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index c2e1daba7..d9da4bc35 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -376,7 +376,7 @@ def read( path: Path, extract: bool = True, dest: Optional[Path] = None, - readonly: bool = False, + readonly: bool = True, ): """Load an existing EKO. From 38c3d1b0ecb00b1345a483991aa66e68e4343e38 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Wed, 16 Aug 2023 17:58:12 +0200 Subject: [PATCH 38/67] Remove outdated test --- extras/matching/check-matching.py | 2 +- tests/eko/io/test_struct.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/extras/matching/check-matching.py b/extras/matching/check-matching.py index e080883cb..f83cc714b 100644 --- a/extras/matching/check-matching.py +++ b/extras/matching/check-matching.py @@ -121,7 +121,7 @@ def collect_data(): data = {} pdf = toy.mkPDF("", 0) for id in th_updates.keys(): - with eko.EKO.open(f"./eko_{id}.tar") as evolution_operator: + with eko.EKO.read(f"./eko_{id}.tar") as evolution_operator: x = evolution_operator.metadata.rotations.targetgrid.raw data[id] = { mu2: el["pdfs"] diff --git a/tests/eko/io/test_struct.py b/tests/eko/io/test_struct.py index 399018ddd..2c50aac6d 100644 --- a/tests/eko/io/test_struct.py +++ b/tests/eko/io/test_struct.py @@ -36,8 +36,6 @@ def test_load_error(self, tmp_path): no_tar_path.write_text("Blub", encoding="utf-8") with pytest.raises(ValueError, match="tar"): struct.EKO.read(no_tar_path) - with pytest.raises(ValueError, match="file mode"): - struct.EKO.open(no_tar_path, "ü") def test_properties(self, eko_factory: EKOFactory): mu = 10.0 From 394bb9f17a74a7b1cad74f475483626a8947246f Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Thu, 17 Aug 2023 16:09:26 +0200 Subject: [PATCH 39/67] Inline extract in load --- src/eko/io/struct.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index d9da4bc35..11a0d6a30 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -337,15 +337,6 @@ def deepcopy(self, path: Path): shutil.copytree(self.paths.root, new.paths.root) new.close() - @staticmethod - def extract(tarpath: Path, dest: Path): - """Extract the content of archive in a target directory.""" - try: - with tarfile.open(tarpath) as tar: - raw.safe_extractall(tar, dest) - except tarfile.ReadError: - raise exceptions.OutputNotTar(f"Not a valid tar archive: '{tarpath}'") - @classmethod def load(cls, path: Path): """Load the EKO from disk information. @@ -389,7 +380,8 @@ def read( """ if extract: dir_ = Path(tempfile.mkdtemp(prefix=TEMP_PREFIX)) if dest is None else dest - cls.extract(path, dir_) + with tarfile.open(path) as tar: + raw.safe_extractall(tar, dir_) else: dir_ = path From 7ecb58e78c63099ac252cbc3fee9faa90c2ffde4 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Thu, 17 Aug 2023 16:23:55 +0200 Subject: [PATCH 40/67] Restrict parts public API --- src/eko/runner/managed.py | 4 +--- src/eko/runner/parts.py | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/eko/runner/managed.py b/src/eko/runner/managed.py index b21882d92..aacd249cf 100644 --- a/src/eko/runner/managed.py +++ b/src/eko/runner/managed.py @@ -12,7 +12,7 @@ """ from pathlib import Path -from ..io.items import Evolution, Matching, Target +from ..io.items import Target from ..io.runcards import OperatorCard, TheoryCard from ..io.struct import EKO from . import operators, parts, recipes @@ -27,12 +27,10 @@ def solve(theory: TheoryCard, operator: OperatorCard, path: Path): recipes.create(eko) for recipe in eko.recipes: - assert isinstance(recipe, Evolution) eko.parts[recipe] = parts.evolve(eko, recipe) # flush the memory del eko.parts[recipe] for recipe in eko.recipes_matching: - assert isinstance(recipe, Matching) eko.parts_matching[recipe] = parts.match(eko, recipe) # flush the memory del eko.parts_matching[recipe] diff --git a/src/eko/runner/parts.py b/src/eko/runner/parts.py index e385b8f49..1ad5bda72 100644 --- a/src/eko/runner/parts.py +++ b/src/eko/runner/parts.py @@ -22,7 +22,7 @@ from . import commons -def managers(eko: EKO) -> dict: +def _managers(eko: EKO) -> dict: """Collect managers for operator computation. .. todo:: @@ -39,7 +39,7 @@ def managers(eko: EKO) -> dict: ) -def blowup_info(eko: EKO) -> dict: +def _blowup_info(eko: EKO) -> dict: """Prepare common information to blow up to flavor basis. Note @@ -65,7 +65,7 @@ def blowup_info(eko: EKO) -> dict: return dict(intrinsic_range=[4, 5, 6], qed=eko.theory_card.order[1] > 0) -def evolve_configs(eko: EKO) -> dict: +def _evolution_configs(eko: EKO) -> dict: """Create configs for :class:`Operator`. .. todo:: @@ -94,11 +94,14 @@ def evolve_configs(eko: EKO) -> dict: def evolve(eko: EKO, recipe: Evolution) -> Operator: """Compute evolution in isolation.""" op = evop.Operator( - evolve_configs(eko), managers(eko), recipe.as_atlas, is_threshold=recipe.cliff + _evolution_configs(eko), + _managers(eko), + recipe.as_atlas, + is_threshold=recipe.cliff, ) op.compute() - binfo = blowup_info(eko) + binfo = _blowup_info(eko) res, err = physical.PhysicalOperator.ad_to_evol_map( op.op_members, op.nf, op.q2_to, **binfo ).to_flavor_basis_tensor(qed=binfo["qed"]) @@ -106,7 +109,7 @@ def evolve(eko: EKO, recipe: Evolution) -> Operator: return Operator(res, err) -def matching_configs(eko: EKO) -> dict: +def _matching_configs(eko: EKO) -> dict: """Create configs for :class:`OperatorMatrixElement`. .. todo:: @@ -117,7 +120,7 @@ def matching_configs(eko: EKO) -> dict: tcard = eko.theory_card ocard = eko.operator_card return dict( - **evolve_configs(eko), + **_evolution_configs(eko), backward_inversion=ocard.configs.inversion_method, intrinsic_range=tcard.heavy.intrinsic_flavors, ) @@ -138,8 +141,8 @@ def match(eko: EKO, recipe: Matching) -> Operator: """ kthr = eko.theory_card.heavy.squared_ratios[recipe.hq - 4] op = ome.OperatorMatrixElement( - matching_configs(eko), - managers(eko), + _matching_configs(eko), + _managers(eko), recipe.hq - 1, recipe.scale, recipe.inverse, @@ -148,7 +151,7 @@ def match(eko: EKO, recipe: Matching) -> Operator: ) op.compute() - binfo = blowup_info(eko) + binfo = _blowup_info(eko) nf_match = op.nf - 1 if recipe.inverse else op.nf res, err = matching_condition.MatchingCondition.split_ad_to_evol_map( op.op_members, nf_match, recipe.scale, **binfo From d5d952c4970e03fb8c1b194d06e3805170e0f308 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Thu, 17 Aug 2023 16:41:27 +0200 Subject: [PATCH 41/67] Restrict operators public API --- src/eko/runner/managed.py | 7 ++----- src/eko/runner/operators.py | 31 +++++++++++++++++------------- tests/eko/runner/test_operators.py | 6 +++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/eko/runner/managed.py b/src/eko/runner/managed.py index aacd249cf..2c3d2c313 100644 --- a/src/eko/runner/managed.py +++ b/src/eko/runner/managed.py @@ -36,12 +36,9 @@ def solve(theory: TheoryCard, operator: OperatorCard, path: Path): del eko.parts_matching[recipe] for ep in operator.evolgrid: - parts_ = operators.retrieve( - operators.parts(ep, eko), eko.parts, eko.parts_matching - ) + components = operators.retrieve(ep, eko) target = Target.from_ep(ep) - eko.operators[target] = operators.join(parts_) + eko.operators[target] = operators.join(components) # flush the memory del eko.parts - del eko.parts_matching del eko.operators[target] diff --git a/src/eko/runner/operators.py b/src/eko/runner/operators.py index 2ccbd1013..702c6479c 100644 --- a/src/eko/runner/operators.py +++ b/src/eko/runner/operators.py @@ -12,7 +12,7 @@ from . import commons, recipes -def retrieve( +def _retrieve( headers: List[Recipe], parts: Inventory, parts_matching: Inventory ) -> List[Operator]: """Retrieve parts to be joined.""" @@ -24,7 +24,18 @@ def retrieve( return elements -def dot4(op1: npt.NDArray, op2: npt.NDArray) -> npt.NDArray: +def _parts(ep: EvolutionPoint, eko: EKO) -> List[Recipe]: + """Determine parts required for the given evolution point operator.""" + atlas = commons.atlas(eko.theory_card, eko.operator_card) + return recipes._elements(ep, atlas) + + +def retrieve(ep: EvolutionPoint, eko: EKO) -> List[Operator]: + """Retrieve parts required for the given evolution point operator.""" + return _retrieve(_parts(ep, eko), eko.parts, eko.parts_matching) + + +def _dot4(op1: npt.NDArray, op2: npt.NDArray) -> npt.NDArray: """Dot product between rank 4 objects. The product is performed considering them as matrices indexed by pairs, so @@ -34,10 +45,10 @@ def dot4(op1: npt.NDArray, op2: npt.NDArray) -> npt.NDArray: return np.einsum("aibj,bjck->aick", op1, op2) -def dotop(op1: Operator, op2: Operator) -> Operator: +def _dotop(op1: Operator, op2: Operator) -> Operator: r"""Dot product between two operators. - Essentially a wrapper of :func:`dot4`, applying linear error propagation, + Essentially a wrapper of :func:`_dot4`, applying linear error propagation, if applicable. Note @@ -67,10 +78,10 @@ def dotop(op1: Operator, op2: Operator) -> Operator: |da_i| \cdot |b_i| + |a_i| \cdot |db_i| + \mathcal{O}(d^2) """ - val = dot4(op1.operator, op2.operator) + val = _dot4(op1.operator, op2.operator) if op1.error is not None and op2.error is not None: - err = dot4(np.abs(op1.operator), np.abs(op2.error)) + dot4( + err = _dot4(np.abs(op1.operator), np.abs(op2.error)) + _dot4( np.abs(op1.error), np.abs(op2.operator) ) else: @@ -93,10 +104,4 @@ def join(elements: List[Operator]) -> Operator: consider if reversing the path... """ - return reduce(dotop, reversed(elements)) - - -def parts(ep: EvolutionPoint, eko: EKO) -> List[Recipe]: - """Determine parts required for the given evolution point operator.""" - atlas = commons.atlas(eko.theory_card, eko.operator_card) - return recipes._elements(ep, atlas) + return reduce(_dotop, reversed(elements)) diff --git a/tests/eko/runner/test_operators.py b/tests/eko/runner/test_operators.py index 8721fca99..77811cf3a 100644 --- a/tests/eko/runner/test_operators.py +++ b/tests/eko/runner/test_operators.py @@ -2,18 +2,18 @@ from eko.io.items import Operator from eko.io.struct import EKO -from eko.runner.operators import join, retrieve +from eko.runner.operators import _retrieve, join def test_retrieve(ekoparts: EKO): evhead, evop = next(iter(ekoparts.parts.cache.items())) matchhead, matchop = next(iter(ekoparts.parts_matching.cache.items())) - els = retrieve([evhead] * 5, ekoparts.parts, ekoparts.parts_matching) + els = _retrieve([evhead] * 5, ekoparts.parts, ekoparts.parts_matching) assert len(els) == 5 assert all(isinstance(el, Operator) for el in els) - els = retrieve( + els = _retrieve( [evhead, matchhead, matchhead], ekoparts.parts, ekoparts.parts_matching ) assert len(els) == 3 From 6a74792e1dab57b11d8084b2c9ee4e6e32d3c632 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Thu, 17 Aug 2023 16:49:43 +0200 Subject: [PATCH 42/67] Update error type in struct opening test --- tests/eko/io/test_struct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/eko/io/test_struct.py b/tests/eko/io/test_struct.py index 2c50aac6d..1370ccdb6 100644 --- a/tests/eko/io/test_struct.py +++ b/tests/eko/io/test_struct.py @@ -34,7 +34,7 @@ def test_load_error(self, tmp_path): # try to read from a non-tar path no_tar_path = tmp_path / "Blub.tar" no_tar_path.write_text("Blub", encoding="utf-8") - with pytest.raises(ValueError, match="tar"): + with pytest.raises(tarfile.ReadError): struct.EKO.read(no_tar_path) def test_properties(self, eko_factory: EKOFactory): From e8c218e0d5e7c7e90ecfd40d22f6f9d58bd2d142 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 17:26:56 +0200 Subject: [PATCH 43/67] Drop new_op_key variable in grid --- src/eko/evolution_operator/grid.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index 1180697a6..9c0c6c1df 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -127,7 +127,6 @@ def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: is_downward = is_downward_path(path) shift = flavor_shift(is_downward) for seg in path[:-1]: - new_op_key = seg kthr = self.config["thresholds_ratios"][seg.nf - shift] ome = OperatorMatrixElement( self.config, @@ -138,13 +137,13 @@ def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: np.log(kthr), self.config["HQ"] == "MSBAR", ) - if new_op_key not in self._threshold_operators: + if seg not in self._threshold_operators: # Compute the operator and store it logger.info("Prepare threshold operator") op_th = Operator(self.config, self.managers, seg, is_threshold=True) op_th.compute() - self._threshold_operators[new_op_key] = op_th - thr_ops.append(self._threshold_operators[new_op_key]) + self._threshold_operators[seg] = op_th + thr_ops.append(self._threshold_operators[seg]) # Compute the matching conditions and store it if seg.target not in self._matching_operators: From 54d9e53401476339afc34bafc0b6718ca523a6b2 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 17:32:28 +0200 Subject: [PATCH 44/67] Define couplings cache key type --- src/eko/couplings.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/eko/couplings.py b/src/eko/couplings.py index 1b3620032..5cd35ef2b 100644 --- a/src/eko/couplings.py +++ b/src/eko/couplings.py @@ -381,6 +381,10 @@ def couplings_expanded_fixed_alphaem(order, couplings_ref, nf, scale_from, scale return np.array([res_as, aem]) +_CouplingsCacheKey = Tuple[float, float, int, float, float] +"""Cache key containing (a0, a1, nf, scale_from, scale_to).""" + + class Couplings: r"""Compute the strong and electromagnetic coupling constants :math:`a_s, a_{em}`. @@ -475,7 +479,7 @@ def assert_positive(name, var): self.decoupled_running, ) # cache - self.cache: Dict[Tuple[float, float, int, float, float], npt.NDArray] = {} + self.cache: Dict[_CouplingsCacheKey, npt.NDArray] = {} @property def mu2_ref(self): From 9b0d8048b98a708a6616e482b2ac955f6475cd30 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 17:38:56 +0200 Subject: [PATCH 45/67] Define label type in apply --- src/ekobox/apply.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ekobox/apply.py b/src/ekobox/apply.py index ace0ccca1..97d1a0168 100644 --- a/src/ekobox/apply.py +++ b/src/ekobox/apply.py @@ -51,13 +51,16 @@ def apply_pdf( CONTRACTION = "ajbk,bk" +_PdfLabel = Union[int, str] +"""PDF identifier: either PID or label.""" + @dataclass class PdfResult: """Helper class to collect PDF results.""" - pdfs: Dict[Union[int, str], float] - errors: Optional[Dict[Union[int, str], float]] = None + pdfs: Dict[_PdfLabel, float] + errors: Optional[Dict[_PdfLabel, float]] = None def apply_pdf_flavor( From 3b576005797436986452c2cab91c726d0d009328 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 17:46:05 +0200 Subject: [PATCH 46/67] Cast labels in evop/Operator --- src/eko/evolution_operator/__init__.py | 4 ++-- src/eko/evolution_operator/operator_matrix_element.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index fea8d15fe..6e008e322 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -607,8 +607,8 @@ class Operator(sv.ModeMixin): log_label = "Evolution" # complete list of possible evolution operators labels - full_labels = list(br.full_labels) - full_labels_qed = list(br.full_unified_labels) + full_labels: Tuple[Tuple[int, int], ...] = br.full_labels + full_labels_qed: Tuple[Tuple[int, int], ...] = br.full_unified_labels def __init__( self, config, managers, segment: Segment, mellin_cut=5e-2, is_threshold=False diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 8966a62b9..deb763499 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -3,7 +3,7 @@ import copy import functools import logging -from typing import List, Tuple +from typing import Tuple import numba as nb import numpy as np @@ -196,7 +196,7 @@ class OperatorMatrixElement(Operator): log_label = "Matching" # complete list of possible matching operators labels - full_labels = [ + full_labels = ( *br.singlet_labels, (br.matching_hplus_pid, 21), (br.matching_hplus_pid, 100), @@ -207,9 +207,9 @@ class OperatorMatrixElement(Operator): (200, br.matching_hminus_pid), (br.matching_hminus_pid, 200), (br.matching_hminus_pid, br.matching_hminus_pid), - ] + ) # still valid in QED since Sdelta and Vdelta matchings are diagonal - full_labels_qed: List[Tuple[int, int]] = copy.deepcopy(full_labels) + full_labels_qed: Tuple[Tuple[int, int], ...] = copy.deepcopy(full_labels) def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): super().__init__(config, managers, Segment(q2, q2, nf)) From bbe955c54302f2ad3ee80cd65dec8bae2c4ccb78 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 17:49:57 +0200 Subject: [PATCH 47/67] Update src/eko/runner/operators.py Co-authored-by: Alessandro Candido --- src/eko/runner/operators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eko/runner/operators.py b/src/eko/runner/operators.py index bfc4ce407..19f53c243 100644 --- a/src/eko/runner/operators.py +++ b/src/eko/runner/operators.py @@ -17,7 +17,7 @@ def retrieve( for head in headers: inv = parts if isinstance(head, Evolution) else parts_matching op = inv[head] - assert isinstance(op, Operator) + assert op is not None elements.append(op) return elements From 16e38092e5eeb42d43348bb07c1d3417e7747a14 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 17:56:01 +0200 Subject: [PATCH 48/67] Introduce OperatorLabel type --- src/eko/evolution_operator/__init__.py | 8 +++++--- src/eko/evolution_operator/operator_matrix_element.py | 3 +-- src/eko/io/types.py | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 6e008e322..3681f0663 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -21,6 +21,7 @@ from .. import basis_rotation as br from .. import interpolation, mellin from .. import scale_variations as sv +from ..io.types import OperatorLabel from ..kernels import non_singlet as ns from ..kernels import non_singlet_qed as qed_ns from ..kernels import singlet as s @@ -579,7 +580,8 @@ def quad_ker_qed( return ker -OpMembers = Dict[Tuple[int, int], OpMember] +OpMembers = Dict[OperatorLabel, OpMember] +"""Map of all operators.""" class Operator(sv.ModeMixin): @@ -607,8 +609,8 @@ class Operator(sv.ModeMixin): log_label = "Evolution" # complete list of possible evolution operators labels - full_labels: Tuple[Tuple[int, int], ...] = br.full_labels - full_labels_qed: Tuple[Tuple[int, int], ...] = br.full_unified_labels + full_labels: Tuple[OperatorLabel, ...] = br.full_labels + full_labels_qed: Tuple[OperatorLabel, ...] = br.full_unified_labels def __init__( self, config, managers, segment: Segment, mellin_cut=5e-2, is_threshold=False diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index deb763499..7a5a3ce6c 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -3,7 +3,6 @@ import copy import functools import logging -from typing import Tuple import numba as nb import numpy as np @@ -209,7 +208,7 @@ class OperatorMatrixElement(Operator): (br.matching_hminus_pid, br.matching_hminus_pid), ) # still valid in QED since Sdelta and Vdelta matchings are diagonal - full_labels_qed: Tuple[Tuple[int, int], ...] = copy.deepcopy(full_labels) + full_labels_qed = copy.deepcopy(full_labels) def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): super().__init__(config, managers, Segment(q2, q2, nf)) diff --git a/src/eko/io/types.py b/src/eko/io/types.py index 5573bafbb..dc8c490c4 100644 --- a/src/eko/io/types.py +++ b/src/eko/io/types.py @@ -1,7 +1,6 @@ """Common type definitions, only used for static analysis.""" import enum -import typing -from typing import Any, Dict, Generic, Tuple, TypeVar +from typing import Any, Dict, Generic, List, Tuple, TypeVar # Energy scales # ------------- @@ -22,8 +21,9 @@ Order = Tuple[int, int] FlavorsNumber = int FlavorIndex = int -IntrinsicFlavors = typing.List[FlavorIndex] -N3LOAdVariation = typing.Tuple[int, int, int, int] +IntrinsicFlavors = List[FlavorIndex] +N3LOAdVariation = Tuple[int, int, int, int] +OperatorLabel = Tuple[int, int] # Evolution coordinates # --------------------- From c9cdc72dfc37932fda2ad91d8f17129cc2a4b3b1 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 17:58:08 +0200 Subject: [PATCH 49/67] Remove list comprension in msbar --- src/eko/msbar_masses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eko/msbar_masses.py b/src/eko/msbar_masses.py index f13582110..ca4fd6731 100644 --- a/src/eko/msbar_masses.py +++ b/src/eko/msbar_masses.py @@ -395,7 +395,7 @@ def sc(thr_masses): heavy_quarks = quark_names[3:] hq_idxs = np.arange(0, 3) if nf_ref > 4: - heavy_quarks = "".join([e for e in reversed(heavy_quarks)]) + heavy_quarks = "".join(reversed(heavy_quarks)) hq_idxs = reversed(hq_idxs) # loop on heavy quarks and compute the msbar masses From c946b3f21745c060aa29109c101ad090daa3a5c8 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 17 Aug 2023 18:25:27 +0200 Subject: [PATCH 50/67] Upgrade banana --- poetry.lock | 1525 ++++++++++++++++++++++++++---------------------- pyproject.toml | 2 +- 2 files changed, 813 insertions(+), 714 deletions(-) diff --git a/poetry.lock b/poetry.lock index 53d012a61..9d5f9c818 100644 --- a/poetry.lock +++ b/poetry.lock @@ -38,14 +38,14 @@ files = [ [[package]] name = "astroid" -version = "2.15.5" +version = "2.15.6" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.7.2" files = [ - {file = "astroid-2.15.5-py3-none-any.whl", hash = "sha256:078e5212f9885fa85fbb0cf0101978a336190aadea6e13305409d099f71b2324"}, - {file = "astroid-2.15.5.tar.gz", hash = "sha256:1039262575027b441137ab4a62a793a9b43defb42c32d5670f38686207cd780f"}, + {file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"}, + {file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"}, ] [package.dependencies] @@ -139,14 +139,14 @@ files = [ [[package]] name = "banana-hep" -version = "0.6.9" +version = "0.6.10" description = "Benchmark QCD physics" category = "main" optional = true python-versions = ">=3.8.0,<3.12" files = [ - {file = "banana_hep-0.6.9-py3-none-any.whl", hash = "sha256:e857b777eb0f64b0bf5e0a2b7cc6afcb5680a60dc3bdd7ce9c34c4bf3b94828b"}, - {file = "banana_hep-0.6.9.tar.gz", hash = "sha256:0b9f5cd3e4e44d5c8117bab93c832784009feb6d87d5a874da0d47fc91ab0514"}, + {file = "banana_hep-0.6.10-py3-none-any.whl", hash = "sha256:e50fcfad55220a9f14b3b3d056f5ba893e1ee2579f875a6786a0273e73f8b3f7"}, + {file = "banana_hep-0.6.10.tar.gz", hash = "sha256:48c584bcb169de4769241ee34f5a067f9f719aaa64f512d3b9251bbe90e80002"}, ] [package.dependencies] @@ -201,14 +201,14 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] [[package]] name = "certifi" -version = "2023.5.7" +version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, - {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, ] [[package]] @@ -290,99 +290,99 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.1.0" +version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, - {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] [[package]] name = "click" -version = "8.1.3" +version = "8.1.6" description = "Composable command line interface toolkit" category = "main" optional = true python-versions = ">=3.7" files = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, + {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, + {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, ] [package.dependencies] @@ -402,18 +402,18 @@ files = [ [[package]] name = "comm" -version = "0.1.3" +version = "0.1.4" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "comm-0.1.3-py3-none-any.whl", hash = "sha256:16613c6211e20223f215fc6d3b266a247b6e2641bf4e0a3ad34cb1aff2aa3f37"}, - {file = "comm-0.1.3.tar.gz", hash = "sha256:a61efa9daffcfbe66fd643ba966f846a624e4e6d6767eda9cf6e993aadaab93e"}, + {file = "comm-0.1.4-py3-none-any.whl", hash = "sha256:6d52794cba11b36ed9860999cd10fd02d6b2eac177068fdd585e1e2f8a96e67a"}, + {file = "comm-0.1.4.tar.gz", hash = "sha256:354e40a59c9dd6db50c5cc6b4acc887d82e9603787f83b68c01a80a923984d15"}, ] [package.dependencies] -traitlets = ">=5.3" +traitlets = ">=4" [package.extras] lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"] @@ -496,72 +496,64 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] [[package]] name = "coverage" -version = "7.2.7" +version = "7.3.0" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, - {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, - {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, - {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, - {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, - {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, - {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, - {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, - {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, - {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, - {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, - {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, - {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, - {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, - {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, - {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, - {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, - {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, + {file = "coverage-7.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5"}, + {file = "coverage-7.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51"}, + {file = "coverage-7.3.0-cp310-cp310-win32.whl", hash = "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527"}, + {file = "coverage-7.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f"}, + {file = "coverage-7.3.0-cp311-cp311-win32.whl", hash = "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482"}, + {file = "coverage-7.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b"}, + {file = "coverage-7.3.0-cp312-cp312-win32.whl", hash = "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321"}, + {file = "coverage-7.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985"}, + {file = "coverage-7.3.0-cp38-cp38-win32.whl", hash = "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9"}, + {file = "coverage-7.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54"}, + {file = "coverage-7.3.0-cp39-cp39-win32.whl", hash = "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3"}, + {file = "coverage-7.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e"}, + {file = "coverage-7.3.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0"}, + {file = "coverage-7.3.0.tar.gz", hash = "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865"}, ] [package.dependencies] @@ -584,30 +576,30 @@ files = [ [[package]] name = "debugpy" -version = "1.6.7" +version = "1.6.7.post1" description = "An implementation of the Debug Adapter Protocol for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "debugpy-1.6.7-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b3e7ac809b991006ad7f857f016fa92014445085711ef111fdc3f74f66144096"}, - {file = "debugpy-1.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3876611d114a18aafef6383695dfc3f1217c98a9168c1aaf1a02b01ec7d8d1e"}, - {file = "debugpy-1.6.7-cp310-cp310-win32.whl", hash = "sha256:33edb4afa85c098c24cc361d72ba7c21bb92f501104514d4ffec1fb36e09c01a"}, - {file = "debugpy-1.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:ed6d5413474e209ba50b1a75b2d9eecf64d41e6e4501977991cdc755dc83ab0f"}, - {file = "debugpy-1.6.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:38ed626353e7c63f4b11efad659be04c23de2b0d15efff77b60e4740ea685d07"}, - {file = "debugpy-1.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279d64c408c60431c8ee832dfd9ace7c396984fd7341fa3116aee414e7dcd88d"}, - {file = "debugpy-1.6.7-cp37-cp37m-win32.whl", hash = "sha256:dbe04e7568aa69361a5b4c47b4493d5680bfa3a911d1e105fbea1b1f23f3eb45"}, - {file = "debugpy-1.6.7-cp37-cp37m-win_amd64.whl", hash = "sha256:f90a2d4ad9a035cee7331c06a4cf2245e38bd7c89554fe3b616d90ab8aab89cc"}, - {file = "debugpy-1.6.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:5224eabbbeddcf1943d4e2821876f3e5d7d383f27390b82da5d9558fd4eb30a9"}, - {file = "debugpy-1.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae1123dff5bfe548ba1683eb972329ba6d646c3a80e6b4c06cd1b1dd0205e9b"}, - {file = "debugpy-1.6.7-cp38-cp38-win32.whl", hash = "sha256:9cd10cf338e0907fdcf9eac9087faa30f150ef5445af5a545d307055141dd7a4"}, - {file = "debugpy-1.6.7-cp38-cp38-win_amd64.whl", hash = "sha256:aaf6da50377ff4056c8ed470da24632b42e4087bc826845daad7af211e00faad"}, - {file = "debugpy-1.6.7-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0679b7e1e3523bd7d7869447ec67b59728675aadfc038550a63a362b63029d2c"}, - {file = "debugpy-1.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de86029696e1b3b4d0d49076b9eba606c226e33ae312a57a46dca14ff370894d"}, - {file = "debugpy-1.6.7-cp39-cp39-win32.whl", hash = "sha256:d71b31117779d9a90b745720c0eab54ae1da76d5b38c8026c654f4a066b0130a"}, - {file = "debugpy-1.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:c0ff93ae90a03b06d85b2c529eca51ab15457868a377c4cc40a23ab0e4e552a3"}, - {file = "debugpy-1.6.7-py2.py3-none-any.whl", hash = "sha256:53f7a456bc50706a0eaabecf2d3ce44c4d5010e46dfc65b6b81a518b42866267"}, - {file = "debugpy-1.6.7.zip", hash = "sha256:c4c2f0810fa25323abfdfa36cbbbb24e5c3b1a42cb762782de64439c575d67f2"}, + {file = "debugpy-1.6.7.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:903bd61d5eb433b6c25b48eae5e23821d4c1a19e25c9610205f5aeaccae64e32"}, + {file = "debugpy-1.6.7.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16882030860081e7dd5aa619f30dec3c2f9a421e69861125f83cc372c94e57d"}, + {file = "debugpy-1.6.7.post1-cp310-cp310-win32.whl", hash = "sha256:eea8d8cfb9965ac41b99a61f8e755a8f50e9a20330938ad8271530210f54e09c"}, + {file = "debugpy-1.6.7.post1-cp310-cp310-win_amd64.whl", hash = "sha256:85969d864c45f70c3996067cfa76a319bae749b04171f2cdeceebe4add316155"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:890f7ab9a683886a0f185786ffbda3b46495c4b929dab083b8c79d6825832a52"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4ac7a4dba28801d184b7fc0e024da2635ca87d8b0a825c6087bb5168e3c0d28"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-win32.whl", hash = "sha256:3370ef1b9951d15799ef7af41f8174194f3482ee689988379763ef61a5456426"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:65b28435a17cba4c09e739621173ff90c515f7b9e8ea469b92e3c28ef8e5cdfb"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:92b6dae8bfbd497c90596bbb69089acf7954164aea3228a99d7e43e5267f5b36"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72f5d2ecead8125cf669e62784ef1e6300f4067b0f14d9f95ee00ae06fc7c4f7"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-win32.whl", hash = "sha256:f0851403030f3975d6e2eaa4abf73232ab90b98f041e3c09ba33be2beda43fcf"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-win_amd64.whl", hash = "sha256:3de5d0f97c425dc49bce4293df6a04494309eedadd2b52c22e58d95107e178d9"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:38651c3639a4e8bbf0ca7e52d799f6abd07d622a193c406be375da4d510d968d"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038c51268367c9c935905a90b1c2d2dbfe304037c27ba9d19fe7409f8cdc710c"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-win32.whl", hash = "sha256:4b9eba71c290852f959d2cf8a03af28afd3ca639ad374d393d53d367f7f685b2"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-win_amd64.whl", hash = "sha256:973a97ed3b434eab0f792719a484566c35328196540676685c975651266fccf9"}, + {file = "debugpy-1.6.7.post1-py2.py3-none-any.whl", hash = "sha256:1093a5c541af079c13ac8c70ab8b24d1d35c8cacb676306cf11e57f699c02926"}, + {file = "debugpy-1.6.7.post1.zip", hash = "sha256:fe87ec0182ef624855d05e6ed7e0b7cb1359d2ffa2a925f8ec2d22e98b75d0ca"}, ] [[package]] @@ -655,14 +647,14 @@ pygments = ["pygments (>=2.2.0)"] [[package]] name = "dill" -version = "0.3.6" -description = "serialize all of python" +version = "0.3.7" +description = "serialize all of Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, - {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, + {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, + {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, ] [package.extras] @@ -670,14 +662,14 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "distlib" -version = "0.3.6" +version = "0.3.7" description = "Distribution utilities" category = "dev" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, + {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, + {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, ] [[package]] @@ -694,14 +686,14 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.1.1" +version = "1.1.3" description = "Backport of PEP 654 (exception groups)" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, - {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, ] [package.extras] @@ -740,14 +732,14 @@ pyrepl = ">=0.8.2" [[package]] name = "fastjsonschema" -version = "2.17.1" +version = "2.18.0" description = "Fastest Python implementation of JSON schema" category = "dev" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.17.1-py3-none-any.whl", hash = "sha256:4b90b252628ca695280924d863fe37234eebadc29c5360d322571233dc9746e0"}, - {file = "fastjsonschema-2.17.1.tar.gz", hash = "sha256:f4eeb8a77cef54861dbf7424ac8ce71306f12cbb086c45131bcba2c6a4f726e3"}, + {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"}, + {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"}, ] [package.extras] @@ -771,46 +763,46 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p [[package]] name = "fonttools" -version = "4.40.0" +version = "4.42.0" description = "Tools to manipulate font files" category = "main" optional = true python-versions = ">=3.8" files = [ - {file = "fonttools-4.40.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b802dcbf9bcff74672f292b2466f6589ab8736ce4dcf36f48eb994c2847c4b30"}, - {file = "fonttools-4.40.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f6e3fa3da923063c286320e728ba2270e49c73386e3a711aa680f4b0747d692"}, - {file = "fonttools-4.40.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fdf60f8a5c6bcce7d024a33f7e4bc7921f5b74e8ea13bccd204f2c8b86f3470"}, - {file = "fonttools-4.40.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91784e21a1a085fac07c6a407564f4a77feb471b5954c9ee55a4f9165151f6c1"}, - {file = "fonttools-4.40.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:05171f3c546f64d78569f10adc0de72561882352cac39ec7439af12304d8d8c0"}, - {file = "fonttools-4.40.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7449e5e306f3a930a8944c85d0cbc8429cba13503372a1a40f23124d6fb09b58"}, - {file = "fonttools-4.40.0-cp310-cp310-win32.whl", hash = "sha256:bae8c13abbc2511e9a855d2142c0ab01178dd66b1a665798f357da0d06253e0d"}, - {file = "fonttools-4.40.0-cp310-cp310-win_amd64.whl", hash = "sha256:425b74a608427499b0e45e433c34ddc350820b6f25b7c8761963a08145157a66"}, - {file = "fonttools-4.40.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:00ab569b2a3e591e00425023ade87e8fef90380c1dde61be7691cb524ca5f743"}, - {file = "fonttools-4.40.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:18ea64ac43e94c9e0c23d7a9475f1026be0e25b10dda8f236fc956188761df97"}, - {file = "fonttools-4.40.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:022c4a16b412293e7f1ce21b8bab7a6f9d12c4ffdf171fdc67122baddb973069"}, - {file = "fonttools-4.40.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:530c5d35109f3e0cea2535742d6a3bc99c0786cf0cbd7bb2dc9212387f0d908c"}, - {file = "fonttools-4.40.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5e00334c66f4e83535384cb5339526d01d02d77f142c23b2f97bd6a4f585497a"}, - {file = "fonttools-4.40.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb52c10fda31159c22c7ed85074e05f8b97da8773ea461706c273e31bcbea836"}, - {file = "fonttools-4.40.0-cp311-cp311-win32.whl", hash = "sha256:6a8d71b9a5c884c72741868e845c0e563c5d83dcaf10bb0ceeec3b4b2eb14c67"}, - {file = "fonttools-4.40.0-cp311-cp311-win_amd64.whl", hash = "sha256:15abb3d055c1b2dff9ce376b6c3db10777cb74b37b52b78f61657634fd348a0d"}, - {file = "fonttools-4.40.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14037c31138fbd21847ad5e5441dfdde003e0a8f3feb5812a1a21fd1c255ffbd"}, - {file = "fonttools-4.40.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:94c915f6716589f78bc00fbc14c5b8de65cfd11ee335d32504f1ef234524cb24"}, - {file = "fonttools-4.40.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37467cee0f32cada2ec08bc16c9c31f9b53ea54b2f5604bf25a1246b5f50593a"}, - {file = "fonttools-4.40.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56d4d85f5374b45b08d2f928517d1e313ea71b4847240398decd0ab3ebbca885"}, - {file = "fonttools-4.40.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8c4305b171b61040b1ee75d18f9baafe58bd3b798d1670078efe2c92436bfb63"}, - {file = "fonttools-4.40.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a954b90d1473c85a22ecf305761d9fd89da93bbd31dae86e7dea436ad2cb5dc9"}, - {file = "fonttools-4.40.0-cp38-cp38-win32.whl", hash = "sha256:1bc4c5b147be8dbc5df9cc8ac5e93ee914ad030fe2a201cc8f02f499db71011d"}, - {file = "fonttools-4.40.0-cp38-cp38-win_amd64.whl", hash = "sha256:8a917828dbfdb1cbe50cf40eeae6fbf9c41aef9e535649ed8f4982b2ef65c091"}, - {file = "fonttools-4.40.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:882983279bf39afe4e945109772c2ffad2be2c90983d6559af8b75c19845a80a"}, - {file = "fonttools-4.40.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c55f1b4109dbc3aeb496677b3e636d55ef46dc078c2a5e3f3db4e90f1c6d2907"}, - {file = "fonttools-4.40.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec468c022d09f1817c691cf884feb1030ef6f1e93e3ea6831b0d8144c06480d1"}, - {file = "fonttools-4.40.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d5adf4ba114f028fc3f5317a221fd8b0f4ef7a2e5524a2b1e0fd891b093791a"}, - {file = "fonttools-4.40.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa83b3f151bc63970f39b2b42a06097c5a22fd7ed9f7ba008e618de4503d3895"}, - {file = "fonttools-4.40.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97d95b8301b62bdece1af943b88bcb3680fd385f88346a4a899ee145913b414a"}, - {file = "fonttools-4.40.0-cp39-cp39-win32.whl", hash = "sha256:1a003608400dd1cca3e089e8c94973c6b51a4fb1ef00ff6d7641617b9242e637"}, - {file = "fonttools-4.40.0-cp39-cp39-win_amd64.whl", hash = "sha256:7961575221e3da0841c75da53833272c520000d76f7f71274dbf43370f8a1065"}, - {file = "fonttools-4.40.0-py3-none-any.whl", hash = "sha256:200729d12461e2038700d31f0d49ad5a7b55855dec7525074979a06b46f88505"}, - {file = "fonttools-4.40.0.tar.gz", hash = "sha256:337b6e83d7ee73c40ea62407f2ce03b07c3459e213b6f332b94a69923b9e1cb9"}, + {file = "fonttools-4.42.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9c456d1f23deff64ffc8b5b098718e149279abdea4d8692dba69172fb6a0d597"}, + {file = "fonttools-4.42.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:150122ed93127a26bc3670ebab7e2add1e0983d30927733aec327ebf4255b072"}, + {file = "fonttools-4.42.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48e82d776d2e93f88ca56567509d102266e7ab2fb707a0326f032fe657335238"}, + {file = "fonttools-4.42.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58c1165f9b2662645de9b19a8c8bdd636b36294ccc07e1b0163856b74f10bafc"}, + {file = "fonttools-4.42.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2d6dc3fa91414ff4daa195c05f946e6a575bd214821e26d17ca50f74b35b0fe4"}, + {file = "fonttools-4.42.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fae4e801b774cc62cecf4a57b1eae4097903fced00c608d9e2bc8f84cd87b54a"}, + {file = "fonttools-4.42.0-cp310-cp310-win32.whl", hash = "sha256:b8600ae7dce6ec3ddfb201abb98c9d53abbf8064d7ac0c8a0d8925e722ccf2a0"}, + {file = "fonttools-4.42.0-cp310-cp310-win_amd64.whl", hash = "sha256:57b68eab183fafac7cd7d464a7bfa0fcd4edf6c67837d14fb09c1c20516cf20b"}, + {file = "fonttools-4.42.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0a1466713e54bdbf5521f2f73eebfe727a528905ff5ec63cda40961b4b1eea95"}, + {file = "fonttools-4.42.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3fb2a69870bfe143ec20b039a1c8009e149dd7780dd89554cc8a11f79e5de86b"}, + {file = "fonttools-4.42.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae881e484702efdb6cf756462622de81d4414c454edfd950b137e9a7352b3cb9"}, + {file = "fonttools-4.42.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27ec3246a088555629f9f0902f7412220c67340553ca91eb540cf247aacb1983"}, + {file = "fonttools-4.42.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ece1886d12bb36c48c00b2031518877f41abae317e3a55620d38e307d799b7e"}, + {file = "fonttools-4.42.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:10dac980f2b975ef74532e2a94bb00e97a95b4595fb7f98db493c474d5f54d0e"}, + {file = "fonttools-4.42.0-cp311-cp311-win32.whl", hash = "sha256:83b98be5d291e08501bd4fc0c4e0f8e6e05b99f3924068b17c5c9972af6fff84"}, + {file = "fonttools-4.42.0-cp311-cp311-win_amd64.whl", hash = "sha256:e35bed436726194c5e6e094fdfb423fb7afaa0211199f9d245e59e11118c576c"}, + {file = "fonttools-4.42.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c36c904ce0322df01e590ba814d5d69e084e985d7e4c2869378671d79662a7d4"}, + {file = "fonttools-4.42.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d54e600a2bcfa5cdaa860237765c01804a03b08404d6affcd92942fa7315ffba"}, + {file = "fonttools-4.42.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01cfe02416b6d416c5c8d15e30315cbcd3e97d1b50d3b34b0ce59f742ef55258"}, + {file = "fonttools-4.42.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f81ed9065b4bd3f4f3ce8e4873cd6a6b3f4e92b1eddefde35d332c6f414acc3"}, + {file = "fonttools-4.42.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:685a4dd6cf31593b50d6d441feb7781a4a7ef61e19551463e14ed7c527b86f9f"}, + {file = "fonttools-4.42.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:329341ba3d86a36e482610db56b30705384cb23bd595eac8cbb045f627778e9d"}, + {file = "fonttools-4.42.0-cp38-cp38-win32.whl", hash = "sha256:4655c480a1a4d706152ff54f20e20cf7609084016f1df3851cce67cef768f40a"}, + {file = "fonttools-4.42.0-cp38-cp38-win_amd64.whl", hash = "sha256:6bd7e4777bff1dcb7c4eff4786998422770f3bfbef8be401c5332895517ba3fa"}, + {file = "fonttools-4.42.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9b55d2a3b360e0c7fc5bd8badf1503ca1c11dd3a1cd20f2c26787ffa145a9c7"}, + {file = "fonttools-4.42.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0df8ef75ba5791e873c9eac2262196497525e3f07699a2576d3ab9ddf41cb619"}, + {file = "fonttools-4.42.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd2363ea7728496827658682d049ffb2e98525e2247ca64554864a8cc945568"}, + {file = "fonttools-4.42.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d40673b2e927f7cd0819c6f04489dfbeb337b4a7b10fc633c89bf4f34ecb9620"}, + {file = "fonttools-4.42.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c8bf88f9e3ce347c716921804ef3a8330cb128284eb6c0b6c4b3574f3c580023"}, + {file = "fonttools-4.42.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:703101eb0490fae32baf385385d47787b73d9ea55253df43b487c89ec767e0d7"}, + {file = "fonttools-4.42.0-cp39-cp39-win32.whl", hash = "sha256:f0290ea7f9945174bd4dfd66e96149037441eb2008f3649094f056201d99e293"}, + {file = "fonttools-4.42.0-cp39-cp39-win_amd64.whl", hash = "sha256:ae7df0ae9ee2f3f7676b0ff6f4ebe48ad0acaeeeaa0b6839d15dbf0709f2c5ef"}, + {file = "fonttools-4.42.0-py3-none-any.whl", hash = "sha256:dfe7fa7e607f7e8b58d0c32501a3a7cac148538300626d1b930082c90ae7f6bd"}, + {file = "fonttools-4.42.0.tar.gz", hash = "sha256:614b1283dca88effd20ee48160518e6de275ce9b5456a3134d5f235523fc5065"}, ] [package.extras] @@ -927,14 +919,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.6.0" +version = "6.8.0" description = "Read metadata from Python packages" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, - {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, ] [package.dependencies] @@ -943,26 +935,26 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "importlib-resources" -version = "5.12.0" +version = "6.0.1" description = "Read resources from Python packages" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, + {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"}, + {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [[package]] name = "iniconfig" @@ -978,14 +970,14 @@ files = [ [[package]] name = "ipykernel" -version = "6.23.2" +version = "6.25.1" description = "IPython Kernel for Jupyter" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.23.2-py3-none-any.whl", hash = "sha256:7ccb6e2d32fd958c21453db494c914f3474908a2fdefd99ab548a5375b548d1f"}, - {file = "ipykernel-6.23.2.tar.gz", hash = "sha256:fcfb67c5b504aa1bfcda1c5b3716636239e0f7b9290958f1c558c79b4c0e7ed5"}, + {file = "ipykernel-6.25.1-py3-none-any.whl", hash = "sha256:c8a2430b357073b37c76c21c52184db42f6b4b0e438e1eb7df3c4440d120497c"}, + {file = "ipykernel-6.25.1.tar.gz", hash = "sha256:050391364c0977e768e354bdb60cbbfbee7cbb943b1af1618382021136ffd42f"}, ] [package.dependencies] @@ -1070,22 +1062,22 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jedi" -version = "0.18.2" +version = "0.19.0" description = "An autocompletion tool for Python that can be used for text editors." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"}, - {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"}, + {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, + {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, ] [package.dependencies] -parso = ">=0.8.0,<0.9.0" +parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] @@ -1108,36 +1100,54 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.17.3" +version = "4.19.0" description = "An implementation of JSON Schema validation for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, + {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, + {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, ] [package.dependencies] -attrs = ">=17.4.0" +attrs = ">=22.2.0" importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +jsonschema-specifications = ">=2023.03.6" pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +[[package]] +name = "jsonschema-specifications" +version = "2023.7.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, + {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, +] + +[package.dependencies] +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +referencing = ">=0.28.0" + [[package]] name = "jupyter-client" -version = "8.2.0" +version = "8.3.0" description = "Jupyter protocol implementation and client libraries" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.2.0-py3-none-any.whl", hash = "sha256:b18219aa695d39e2ad570533e0d71fb7881d35a873051054a84ee2a17c4b7389"}, - {file = "jupyter_client-8.2.0.tar.gz", hash = "sha256:9fe233834edd0e6c0aa5f05ca2ab4bdea1842bfd2d8a932878212fc5301ddaf0"}, + {file = "jupyter_client-8.3.0-py3-none-any.whl", hash = "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158"}, + {file = "jupyter_client-8.3.0.tar.gz", hash = "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f"}, ] [package.dependencies] @@ -1326,36 +1336,36 @@ files = [ [[package]] name = "llvmlite" -version = "0.40.0" +version = "0.40.1" description = "lightweight wrapper around basic LLVM functionality" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "llvmlite-0.40.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90a46db1ed219d93ef05245ec17cf243074ec2b2687209cb310a803a2c2510dc"}, - {file = "llvmlite-0.40.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b9d742b66023298532d0e7beddd3d9f04334c046df7a02a1ec2ba8b4046a978c"}, - {file = "llvmlite-0.40.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ff38c309dc758b996d556e599e00647e6b8dbd21125c06b2d0584a9984a2288"}, - {file = "llvmlite-0.40.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ecb8cdee35bbbdad9b331f446641977645de1973f6270bf4194307a1753666"}, - {file = "llvmlite-0.40.0-cp310-cp310-win32.whl", hash = "sha256:83dd5148f6ddd4d35585b69ebaa50605fdf8011a5b7259a0463afd4aefc62414"}, - {file = "llvmlite-0.40.0-cp310-cp310-win_amd64.whl", hash = "sha256:f72d6ccbfd9cc7da43098fcef23ffbe173ce2d986215072dbb2e7929412f9ff8"}, - {file = "llvmlite-0.40.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbf19077144e159406ef222348d5330d5061177fb79d3f7f82abf2cf29b77c0b"}, - {file = "llvmlite-0.40.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4732d6c981f658f014dd2ab2b682ac631cd12a6695e77c2d460cc68dc767868"}, - {file = "llvmlite-0.40.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2754c4d2b6f027ab45425abd94dee4cbd228b598531b1e9e1fc15f3298265d88"}, - {file = "llvmlite-0.40.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb79b992bdc2e62c5f5f86263d5546b5298d498e7c1a9d64b3a6f0d31f46ba5b"}, - {file = "llvmlite-0.40.0-cp311-cp311-win_amd64.whl", hash = "sha256:be0ff5b68a86e47a7ec6cd5389bb17b4b8f020b981628c9e714dc2cfdbe89c86"}, - {file = "llvmlite-0.40.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f5d4445eccd9c9c5639b35cb6279231f97cbd77a1c49fb41c05081ff96e041db"}, - {file = "llvmlite-0.40.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:060f00611d8e65d6db80cabba17fbefde9ebefbfb6937fe5677f06cd3e7bbe3c"}, - {file = "llvmlite-0.40.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58f5ba5febb2372418a3d37bd76d51bb987276a6fd979c2f2772b60b9061e575"}, - {file = "llvmlite-0.40.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d1622237e6ce543ac185751f782c7e10cabe45abf2de802cd5dca8023805a5c"}, - {file = "llvmlite-0.40.0-cp38-cp38-win32.whl", hash = "sha256:06803a1a38f911576bbe63a4082334d6661c59f2080e4681de1c66ec4924b0ac"}, - {file = "llvmlite-0.40.0-cp38-cp38-win_amd64.whl", hash = "sha256:87c2114567f95c715ae35b03d82caa0df66a978c93a1ff752964949e9ce596d5"}, - {file = "llvmlite-0.40.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a3382d81fcda57f5502f45a9ca62e0c9103fabd5f817c9820c7e61b9375f3d7"}, - {file = "llvmlite-0.40.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:260b0241c17a1ec585020e1df58ed30b9975c3573c619fa1724ceb4cd53cbe42"}, - {file = "llvmlite-0.40.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f980992b6c9dfee20a1608c5a4d875f8a52d76353ca02470550a85be6e5d3680"}, - {file = "llvmlite-0.40.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52eee9e245ef6eb911d6c2a3a1a66378745a40c637284386031b0915754f457e"}, - {file = "llvmlite-0.40.0-cp39-cp39-win32.whl", hash = "sha256:d27c2ec699b820296659dfd36ead1c527eb190c6d5cb3de24bfbee1024bdc20a"}, - {file = "llvmlite-0.40.0-cp39-cp39-win_amd64.whl", hash = "sha256:6cf84141d1793c69285b88acf4216370cb831eab99778546a2a9002fadac932d"}, - {file = "llvmlite-0.40.0.tar.gz", hash = "sha256:c910b8fbfd67b8e9d0b10ebc012b23cd67cbecef1b96f00d391ddd298d71671c"}, + {file = "llvmlite-0.40.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:84ce9b1c7a59936382ffde7871978cddcda14098e5a76d961e204523e5c372fb"}, + {file = "llvmlite-0.40.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3673c53cb21c65d2ff3704962b5958e967c6fc0bd0cff772998face199e8d87b"}, + {file = "llvmlite-0.40.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bba2747cf5b4954e945c287fe310b3fcc484e2a9d1b0c273e99eb17d103bb0e6"}, + {file = "llvmlite-0.40.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbd5e82cc990e5a3e343a3bf855c26fdfe3bfae55225f00efd01c05bbda79918"}, + {file = "llvmlite-0.40.1-cp310-cp310-win32.whl", hash = "sha256:09f83ea7a54509c285f905d968184bba00fc31ebf12f2b6b1494d677bb7dde9b"}, + {file = "llvmlite-0.40.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b37297f3cbd68d14a97223a30620589d98ad1890e5040c9e5fc181063f4ed49"}, + {file = "llvmlite-0.40.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a66a5bd580951751b4268f4c3bddcef92682814d6bc72f3cd3bb67f335dd7097"}, + {file = "llvmlite-0.40.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:467b43836b388eaedc5a106d76761e388dbc4674b2f2237bc477c6895b15a634"}, + {file = "llvmlite-0.40.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c23edd196bd797dc3a7860799054ea3488d2824ecabc03f9135110c2e39fcbc"}, + {file = "llvmlite-0.40.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a36d9f244b6680cb90bbca66b146dabb2972f4180c64415c96f7c8a2d8b60a36"}, + {file = "llvmlite-0.40.1-cp311-cp311-win_amd64.whl", hash = "sha256:5b3076dc4e9c107d16dc15ecb7f2faf94f7736cd2d5e9f4dc06287fd672452c1"}, + {file = "llvmlite-0.40.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a7525db121f2e699809b539b5308228854ccab6693ecb01b52c44a2f5647e20"}, + {file = "llvmlite-0.40.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:84747289775d0874e506f907a4513db889471607db19b04de97d144047fec885"}, + {file = "llvmlite-0.40.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e35766e42acef0fe7d1c43169a8ffc327a47808fae6a067b049fe0e9bbf84dd5"}, + {file = "llvmlite-0.40.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cda71de10a1f48416309e408ea83dab5bf36058f83e13b86a2961defed265568"}, + {file = "llvmlite-0.40.1-cp38-cp38-win32.whl", hash = "sha256:96707ebad8b051bbb4fc40c65ef93b7eeee16643bd4d579a14d11578e4b7a647"}, + {file = "llvmlite-0.40.1-cp38-cp38-win_amd64.whl", hash = "sha256:e44f854dc11559795bcdeaf12303759e56213d42dabbf91a5897aa2d8b033810"}, + {file = "llvmlite-0.40.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f643d15aacd0b0b0dc8b74b693822ba3f9a53fa63bc6a178c2dba7cc88f42144"}, + {file = "llvmlite-0.40.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39a0b4d0088c01a469a5860d2e2d7a9b4e6a93c0f07eb26e71a9a872a8cadf8d"}, + {file = "llvmlite-0.40.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9329b930d699699846623054121ed105fd0823ed2180906d3b3235d361645490"}, + {file = "llvmlite-0.40.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2dbbb8424037ca287983b115a29adf37d806baf7e1bf4a67bd2cffb74e085ed"}, + {file = "llvmlite-0.40.1-cp39-cp39-win32.whl", hash = "sha256:e74e7bec3235a1e1c9ad97d897a620c5007d0ed80c32c84c1d787e7daa17e4ec"}, + {file = "llvmlite-0.40.1-cp39-cp39-win_amd64.whl", hash = "sha256:ff8f31111bb99d135ff296757dc81ab36c2dee54ed4bd429158a96da9807c316"}, + {file = "llvmlite-0.40.1.tar.gz", hash = "sha256:5cdb0d45df602099d833d50bd9e81353a5e036242d3c003c5b294fc61d1986b4"}, ] [[package]] @@ -1470,53 +1480,53 @@ files = [ [[package]] name = "matplotlib" -version = "3.7.1" +version = "3.7.2" description = "Python plotting package" category = "main" optional = true python-versions = ">=3.8" files = [ - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"}, - {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"}, - {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"}, - {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"}, - {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"}, - {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"}, - {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"}, - {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"}, - {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"}, - {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"}, + {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"}, + {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"}, + {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"}, + {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"}, + {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"}, + {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"}, + {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"}, + {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"}, + {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"}, + {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"}, + {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"}, + {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"}, + {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"}, + {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"}, + {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"}, + {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"}, + {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"}, + {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"}, + {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"}, + {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"}, + {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"}, + {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"}, + {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"}, + {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"}, + {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"}, + {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"}, + {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"}, + {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"}, + {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"}, + {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"}, + {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"}, + {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"}, + {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"}, ] [package.dependencies] @@ -1528,7 +1538,7 @@ kiwisolver = ">=1.0.1" numpy = ">=1.20" packaging = ">=20.0" pillow = ">=6.2.0" -pyparsing = ">=2.3.1" +pyparsing = ">=2.3.1,<3.1" python-dateutil = ">=2.7" [[package]] @@ -1560,14 +1570,14 @@ files = [ [[package]] name = "mistune" -version = "2.0.5" -description = "A sane Markdown parser with useful plugins and renderers" +version = "3.0.1" +description = "A sane and fast Markdown parser with useful plugins and renderers" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"}, - {file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"}, + {file = "mistune-3.0.1-py3-none-any.whl", hash = "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6"}, + {file = "mistune-3.0.1.tar.gz", hash = "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c"}, ] [[package]] @@ -1595,14 +1605,14 @@ test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>= [[package]] name = "nbconvert" -version = "7.5.0" +version = "7.7.4" description = "Converting Jupyter Notebooks" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "nbconvert-7.5.0-py3-none-any.whl", hash = "sha256:852e44392d5650ef217a5ce3a8050747051d4e6ba75f0574cb5435049ee6c0d9"}, - {file = "nbconvert-7.5.0.tar.gz", hash = "sha256:f78fd22fd2410b960d5d9bcecf3e1d6c7bdc5fec2c865964c84aa4e74e6e88da"}, + {file = "nbconvert-7.7.4-py3-none-any.whl", hash = "sha256:ace26f4386d08eb5c55833596a942048c5502a95e05590cb523826a749a40a37"}, + {file = "nbconvert-7.7.4.tar.gz", hash = "sha256:1113d039fa3fc3a846ffa5a3b0a019e85aaa94c566a09fa0c400fb7638e46087"}, ] [package.dependencies] @@ -1614,7 +1624,7 @@ jinja2 = ">=3.0" jupyter-core = ">=4.7" jupyterlab-pygments = "*" markupsafe = ">=2.0" -mistune = ">=2.0.3,<3" +mistune = ">=2.0.3,<4" nbclient = ">=0.5.0" nbformat = ">=5.7" packaging = "*" @@ -1629,19 +1639,19 @@ docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sp qtpdf = ["nbconvert[qtpng]"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] -test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] -webpdf = ["pyppeteer (>=1,<1.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] +webpdf = ["playwright"] [[package]] name = "nbformat" -version = "5.9.0" +version = "5.9.2" description = "The Jupyter Notebook format" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "nbformat-5.9.0-py3-none-any.whl", hash = "sha256:8c8fa16d6d05062c26177754bfbfac22de644888e2ef69d27ad2a334cf2576e5"}, - {file = "nbformat-5.9.0.tar.gz", hash = "sha256:e98ebb6120c3efbafdee2a40af2a140cadee90bb06dd69a2a63d9551fcc7f976"}, + {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, + {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, ] [package.dependencies] @@ -1676,48 +1686,48 @@ traitlets = ">=5" [[package]] name = "nest-asyncio" -version = "1.5.6" +version = "1.5.7" description = "Patch asyncio to allow nested event loops" category = "dev" optional = false python-versions = ">=3.5" files = [ - {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"}, - {file = "nest_asyncio-1.5.6.tar.gz", hash = "sha256:d267cc1ff794403f7df692964d1d2a3fa9418ffea2a3f6859a439ff482fef290"}, + {file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"}, + {file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"}, ] [[package]] name = "numba" -version = "0.57.0" +version = "0.57.1" description = "compiling Python code using LLVM" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "numba-0.57.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2e2c14c411545e80bf0f1a33232fb0bd6aa3368f86e56eeffc7f6d3ac16ea3fd"}, - {file = "numba-0.57.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6b3382c56d805ffcdc7b46eb69a906be733dd35b84be14abba8e5fd27d7916b2"}, - {file = "numba-0.57.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:133cba9b5002bf67f6f73d9b3050d919c1be91326bbdcccfdf3259bcfb1cec0e"}, - {file = "numba-0.57.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d92a17ee849574665c5d94e9c9b862e469e1231d3dbb9e58e58b30b4bb0cbce9"}, - {file = "numba-0.57.0-cp310-cp310-win32.whl", hash = "sha256:abc90c3d303a67ae5194770a6f0d0a83edf076683b8a426349a27b91d98e00d1"}, - {file = "numba-0.57.0-cp310-cp310-win_amd64.whl", hash = "sha256:430f43c96f866ca4fe6008d8aa28bb608911d908ff94f879e0dbad7768ef9869"}, - {file = "numba-0.57.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:069f7d8fddad4c0eb1d7534c2a18098fe50473dc77832b409176002e9011b96f"}, - {file = "numba-0.57.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:79daa130fc9e4ebd1eea0a594d1de86d8a4366989f5fab93c482246b502520db"}, - {file = "numba-0.57.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:274f4db4814ebd5ec81697acfc36df04a865b86610d7714905185b753f3f9baf"}, - {file = "numba-0.57.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0106ee441e3f69cc6f17cb470c4fcccd592e0606567d43245635d72b071ab88e"}, - {file = "numba-0.57.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5d31b4d95000d86ffa9652ab5bcfa0ea30e6c3fc40e610147d4f2f00116703d"}, - {file = "numba-0.57.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e0b8de39bf17519435937b53276dfb02e2eb8bc27cd211c8eeb01ffed1cab6b"}, - {file = "numba-0.57.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:18d90fa6fcd5b796999392a8ea67f2fbccecf8dabcea726e2e721c79f40566a6"}, - {file = "numba-0.57.0-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4f62528c7c8c5f97e9689fd788e420b68c67ee0a1a9a7715a57fd584b7aef1e"}, - {file = "numba-0.57.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fd12cf0b431676c08057685e229ea5daaa1ec8efba2506c38671734ace49c2d7"}, - {file = "numba-0.57.0-cp38-cp38-win32.whl", hash = "sha256:e5f11b1d435fb4d1d1b68fa68ff456d632dc4bfd40b18825ff80d6081d1afb26"}, - {file = "numba-0.57.0-cp38-cp38-win_amd64.whl", hash = "sha256:5810ed2d6d22eb3c48bedfac2187fc44bb90e05f02d47fd31059e69207ae4106"}, - {file = "numba-0.57.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eddba74493d4003a42cd61ff7feca4928a94a45553d1fddac77a5cc339f6f4f9"}, - {file = "numba-0.57.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:110be5e1213d0a3d5fc691e921a000779500620196d99cee9908fce83d1e48df"}, - {file = "numba-0.57.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f949018ab9c467d38f14fe17db4df0d4a1c664be802189e2d6c5a434d9ffd4f6"}, - {file = "numba-0.57.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9fc0cd4ec93a1e3877985e10ed5837ed2991c83aa4b7ca574caae5c8b448cc4b"}, - {file = "numba-0.57.0-cp39-cp39-win32.whl", hash = "sha256:83d4f21c98eed3001e9896a43a1ce9c825999c03f7eb39ddd1c2d07a76708392"}, - {file = "numba-0.57.0-cp39-cp39-win_amd64.whl", hash = "sha256:9173d00c6753212b68e4fd319cfa96c21b2263949452c97b034e78ce09539dee"}, - {file = "numba-0.57.0.tar.gz", hash = "sha256:2af6d81067a5bdc13960c6d2519dbabbf4d5d597cf75d640c5aeaefd48c6420a"}, + {file = "numba-0.57.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db8268eb5093cae2288942a8cbd69c9352f6fe6e0bfa0a9a27679436f92e4248"}, + {file = "numba-0.57.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:643cb09a9ba9e1bd8b060e910aeca455e9442361e80fce97690795ff9840e681"}, + {file = "numba-0.57.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:53e9fab973d9e82c9f8449f75994a898daaaf821d84f06fbb0b9de2293dd9306"}, + {file = "numba-0.57.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c0602e4f896e6a6d844517c3ab434bc978e7698a22a733cc8124465898c28fa8"}, + {file = "numba-0.57.1-cp310-cp310-win32.whl", hash = "sha256:3d6483c27520d16cf5d122868b79cad79e48056ecb721b52d70c126bed65431e"}, + {file = "numba-0.57.1-cp310-cp310-win_amd64.whl", hash = "sha256:a32ee263649aa3c3587b833d6311305379529570e6c20deb0c6f4fb5bc7020db"}, + {file = "numba-0.57.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c078f84b5529a7fdb8413bb33d5100f11ec7b44aa705857d9eb4e54a54ff505"}, + {file = "numba-0.57.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e447c4634d1cc99ab50d4faa68f680f1d88b06a2a05acf134aa6fcc0342adeca"}, + {file = "numba-0.57.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4838edef2df5f056cb8974670f3d66562e751040c448eb0b67c7e2fec1726649"}, + {file = "numba-0.57.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9b17fbe4a69dcd9a7cd49916b6463cd9a82af5f84911feeb40793b8bce00dfa7"}, + {file = "numba-0.57.1-cp311-cp311-win_amd64.whl", hash = "sha256:93df62304ada9b351818ba19b1cfbddaf72cd89348e81474326ca0b23bf0bae1"}, + {file = "numba-0.57.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8e00ca63c5d0ad2beeb78d77f087b3a88c45ea9b97e7622ab2ec411a868420ee"}, + {file = "numba-0.57.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ff66d5b022af6c7d81ddbefa87768e78ed4f834ab2da6ca2fd0d60a9e69b94f5"}, + {file = "numba-0.57.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:60ec56386076e9eed106a87c96626d5686fbb16293b9834f0849cf78c9491779"}, + {file = "numba-0.57.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c057ccedca95df23802b6ccad86bb318be624af45b5a38bb8412882be57a681"}, + {file = "numba-0.57.1-cp38-cp38-win32.whl", hash = "sha256:5a82bf37444039c732485c072fda21a361790ed990f88db57fd6941cd5e5d307"}, + {file = "numba-0.57.1-cp38-cp38-win_amd64.whl", hash = "sha256:9bcc36478773ce838f38afd9a4dfafc328d4ffb1915381353d657da7f6473282"}, + {file = "numba-0.57.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae50c8c90c2ce8057f9618b589223e13faa8cbc037d8f15b4aad95a2c33a0582"}, + {file = "numba-0.57.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9a1b2b69448e510d672ff9a6b18d2db9355241d93c6a77677baa14bec67dc2a0"}, + {file = "numba-0.57.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3cf78d74ad9d289fbc1e5b1c9f2680fca7a788311eb620581893ab347ec37a7e"}, + {file = "numba-0.57.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f47dd214adc5dcd040fe9ad2adbd2192133c9075d2189ce1b3d5f9d72863ef05"}, + {file = "numba-0.57.1-cp39-cp39-win32.whl", hash = "sha256:a3eac19529956185677acb7f01864919761bfffbb9ae04bbbe5e84bbc06cfc2b"}, + {file = "numba-0.57.1-cp39-cp39-win_amd64.whl", hash = "sha256:9587ba1bf5f3035575e45562ada17737535c6d612df751e811d702693a72d95e"}, + {file = "numba-0.57.1.tar.gz", hash = "sha256:33c0500170d213e66d90558ad6aca57d3e03e97bb11da82e6d87ab793648cb17"}, ] [package.dependencies] @@ -1727,40 +1737,40 @@ numpy = ">=1.21,<1.25" [[package]] name = "numpy" -version = "1.24.3" +version = "1.24.4" description = "Fundamental package for array computing in Python" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, - {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, - {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, - {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, - {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, - {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, - {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, - {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, - {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, - {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, - {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, ] [[package]] @@ -1937,78 +1947,68 @@ files = [ [[package]] name = "pillow" -version = "9.5.0" +version = "10.0.0" description = "Python Imaging Library (Fork)" category = "main" optional = true -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, - {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, - {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, - {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, - {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, - {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, - {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, - {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, - {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, - {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, - {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, - {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, - {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, - {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, - {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, - {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, - {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, + {file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891"}, + {file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf"}, + {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3"}, + {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992"}, + {file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de"}, + {file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485"}, + {file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629"}, + {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, + {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, + {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, + {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, + {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, + {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff"}, + {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, + {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, + {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, + {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, + {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, + {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51"}, + {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86"}, + {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7"}, + {file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0"}, + {file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa"}, + {file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba"}, + {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3"}, + {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017"}, + {file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3"}, + {file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396"}, ] [package.extras] @@ -2029,30 +2029,30 @@ files = [ [[package]] name = "platformdirs" -version = "3.5.3" +version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.3-py3-none-any.whl", hash = "sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed"}, - {file = "platformdirs-3.5.3.tar.gz", hash = "sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e"}, + {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, + {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] name = "pluggy" -version = "1.0.0" +version = "1.2.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, ] [package.extras] @@ -2061,14 +2061,14 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prompt-toolkit" -version = "3.0.38" +version = "3.0.39" description = "Library for building powerful interactive command lines in Python" category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, - {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, + {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, + {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, ] [package.dependencies] @@ -2178,14 +2178,14 @@ files = [ [[package]] name = "pygments" -version = "2.15.1" +version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, ] [package.extras] @@ -2193,18 +2193,18 @@ plugins = ["importlib-metadata"] [[package]] name = "pylint" -version = "2.17.4" +version = "2.17.5" description = "python code static checker" category = "dev" optional = false python-versions = ">=3.7.2" files = [ - {file = "pylint-2.17.4-py3-none-any.whl", hash = "sha256:7a1145fb08c251bdb5cca11739722ce64a63db479283d10ce718b2460e54123c"}, - {file = "pylint-2.17.4.tar.gz", hash = "sha256:5dcf1d9e19f41f38e4e85d10f511e5b9c35e1aa74251bf95cdd8cb23584e2db1"}, + {file = "pylint-2.17.5-py3-none-any.whl", hash = "sha256:73995fb8216d3bed149c8d51bba25b2c52a8251a2c8ac846ec668ce38fab5413"}, + {file = "pylint-2.17.5.tar.gz", hash = "sha256:f7b601cbc06fef7e62a754e2b41294c2aa31f1cb659624b9a85bcba29eaf8252"}, ] [package.dependencies] -astroid = ">=2.15.4,<=2.17.0-dev0" +astroid = ">=2.15.6,<=2.17.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, @@ -2258,53 +2258,16 @@ files = [ {file = "pyrepl-0.9.0.tar.gz", hash = "sha256:292570f34b5502e871bbb966d639474f2b57fbfcd3373c2d6a2f3d56e681a775"}, ] -[[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, - {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, - {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, - {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, - {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, - {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, -] - [[package]] name = "pytest" -version = "7.3.2" +version = "7.4.0" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"}, - {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"}, + {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, + {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, ] [package.dependencies] @@ -2416,144 +2379,176 @@ files = [ [[package]] name = "pyyaml" -version = "6.0" +version = "6.0.1" description = "YAML parser and emitter for Python" category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] name = "pyzmq" -version = "25.1.0" +version = "25.1.1" description = "Python bindings for 0MQ" category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:1a6169e69034eaa06823da6a93a7739ff38716142b3596c180363dee729d713d"}, - {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:19d0383b1f18411d137d891cab567de9afa609b214de68b86e20173dc624c101"}, - {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1e931d9a92f628858a50f5bdffdfcf839aebe388b82f9d2ccd5d22a38a789dc"}, - {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97d984b1b2f574bc1bb58296d3c0b64b10e95e7026f8716ed6c0b86d4679843f"}, - {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:154bddda2a351161474b36dba03bf1463377ec226a13458725183e508840df89"}, - {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cb6d161ae94fb35bb518b74bb06b7293299c15ba3bc099dccd6a5b7ae589aee3"}, - {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:90146ab578931e0e2826ee39d0c948d0ea72734378f1898939d18bc9c823fcf9"}, - {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:831ba20b660b39e39e5ac8603e8193f8fce1ee03a42c84ade89c36a251449d80"}, - {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3a522510e3434e12aff80187144c6df556bb06fe6b9d01b2ecfbd2b5bfa5c60c"}, - {file = "pyzmq-25.1.0-cp310-cp310-win32.whl", hash = "sha256:be24a5867b8e3b9dd5c241de359a9a5217698ff616ac2daa47713ba2ebe30ad1"}, - {file = "pyzmq-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:5693dcc4f163481cf79e98cf2d7995c60e43809e325b77a7748d8024b1b7bcba"}, - {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:13bbe36da3f8aaf2b7ec12696253c0bf6ffe05f4507985a8844a1081db6ec22d"}, - {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:69511d604368f3dc58d4be1b0bad99b61ee92b44afe1cd9b7bd8c5e34ea8248a"}, - {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a983c8694667fd76d793ada77fd36c8317e76aa66eec75be2653cef2ea72883"}, - {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:332616f95eb400492103ab9d542b69d5f0ff628b23129a4bc0a2fd48da6e4e0b"}, - {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58416db767787aedbfd57116714aad6c9ce57215ffa1c3758a52403f7c68cff5"}, - {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cad9545f5801a125f162d09ec9b724b7ad9b6440151b89645241d0120e119dcc"}, - {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d6128d431b8dfa888bf51c22a04d48bcb3d64431caf02b3cb943269f17fd2994"}, - {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2b15247c49d8cbea695b321ae5478d47cffd496a2ec5ef47131a9e79ddd7e46c"}, - {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:442d3efc77ca4d35bee3547a8e08e8d4bb88dadb54a8377014938ba98d2e074a"}, - {file = "pyzmq-25.1.0-cp311-cp311-win32.whl", hash = "sha256:65346f507a815a731092421d0d7d60ed551a80d9b75e8b684307d435a5597425"}, - {file = "pyzmq-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b45d722046fea5a5694cba5d86f21f78f0052b40a4bbbbf60128ac55bfcc7b6"}, - {file = "pyzmq-25.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f45808eda8b1d71308c5416ef3abe958f033fdbb356984fabbfc7887bed76b3f"}, - {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b697774ea8273e3c0460cf0bba16cd85ca6c46dfe8b303211816d68c492e132"}, - {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b324fa769577fc2c8f5efcd429cef5acbc17d63fe15ed16d6dcbac2c5eb00849"}, - {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5873d6a60b778848ce23b6c0ac26c39e48969823882f607516b91fb323ce80e5"}, - {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f0d9e7ba6a815a12c8575ba7887da4b72483e4cfc57179af10c9b937f3f9308f"}, - {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:414b8beec76521358b49170db7b9967d6974bdfc3297f47f7d23edec37329b00"}, - {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:01f06f33e12497dca86353c354461f75275a5ad9eaea181ac0dc1662da8074fa"}, - {file = "pyzmq-25.1.0-cp36-cp36m-win32.whl", hash = "sha256:b5a07c4f29bf7cb0164664ef87e4aa25435dcc1f818d29842118b0ac1eb8e2b5"}, - {file = "pyzmq-25.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:968b0c737797c1809ec602e082cb63e9824ff2329275336bb88bd71591e94a90"}, - {file = "pyzmq-25.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:47b915ba666c51391836d7ed9a745926b22c434efa76c119f77bcffa64d2c50c"}, - {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5af31493663cf76dd36b00dafbc839e83bbca8a0662931e11816d75f36155897"}, - {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5489738a692bc7ee9a0a7765979c8a572520d616d12d949eaffc6e061b82b4d1"}, - {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1fc56a0221bdf67cfa94ef2d6ce5513a3d209c3dfd21fed4d4e87eca1822e3a3"}, - {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:75217e83faea9edbc29516fc90c817bc40c6b21a5771ecb53e868e45594826b0"}, - {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3830be8826639d801de9053cf86350ed6742c4321ba4236e4b5568528d7bfed7"}, - {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3575699d7fd7c9b2108bc1c6128641a9a825a58577775ada26c02eb29e09c517"}, - {file = "pyzmq-25.1.0-cp37-cp37m-win32.whl", hash = "sha256:95bd3a998d8c68b76679f6b18f520904af5204f089beebb7b0301d97704634dd"}, - {file = "pyzmq-25.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:dbc466744a2db4b7ca05589f21ae1a35066afada2f803f92369f5877c100ef62"}, - {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:3bed53f7218490c68f0e82a29c92335daa9606216e51c64f37b48eb78f1281f4"}, - {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eb52e826d16c09ef87132c6e360e1879c984f19a4f62d8a935345deac43f3c12"}, - {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ddbef8b53cd16467fdbfa92a712eae46dd066aa19780681a2ce266e88fbc7165"}, - {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9301cf1d7fc1ddf668d0abbe3e227fc9ab15bc036a31c247276012abb921b5ff"}, - {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e23a8c3b6c06de40bdb9e06288180d630b562db8ac199e8cc535af81f90e64b"}, - {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4a82faae00d1eed4809c2f18b37f15ce39a10a1c58fe48b60ad02875d6e13d80"}, - {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8398a1b1951aaa330269c35335ae69744be166e67e0ebd9869bdc09426f3871"}, - {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d40682ac60b2a613d36d8d3a0cd14fbdf8e7e0618fbb40aa9fa7b796c9081584"}, - {file = "pyzmq-25.1.0-cp38-cp38-win32.whl", hash = "sha256:33d5c8391a34d56224bccf74f458d82fc6e24b3213fc68165c98b708c7a69325"}, - {file = "pyzmq-25.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c66b7ff2527e18554030319b1376d81560ca0742c6e0b17ff1ee96624a5f1afd"}, - {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:af56229ea6527a849ac9fb154a059d7e32e77a8cba27e3e62a1e38d8808cb1a5"}, - {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bdca18b94c404af6ae5533cd1bc310c4931f7ac97c148bbfd2cd4bdd62b96253"}, - {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b6b42f7055bbc562f63f3df3b63e3dd1ebe9727ff0f124c3aa7bcea7b3a00f9"}, - {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c2fc7aad520a97d64ffc98190fce6b64152bde57a10c704b337082679e74f67"}, - {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be86a26415a8b6af02cd8d782e3a9ae3872140a057f1cadf0133de685185c02b"}, - {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:851fb2fe14036cfc1960d806628b80276af5424db09fe5c91c726890c8e6d943"}, - {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2a21fec5c3cea45421a19ccbe6250c82f97af4175bc09de4d6dd78fb0cb4c200"}, - {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bad172aba822444b32eae54c2d5ab18cd7dee9814fd5c7ed026603b8cae2d05f"}, - {file = "pyzmq-25.1.0-cp39-cp39-win32.whl", hash = "sha256:4d67609b37204acad3d566bb7391e0ecc25ef8bae22ff72ebe2ad7ffb7847158"}, - {file = "pyzmq-25.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:71c7b5896e40720d30cd77a81e62b433b981005bbff0cb2f739e0f8d059b5d99"}, - {file = "pyzmq-25.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4cb27ef9d3bdc0c195b2dc54fcb8720e18b741624686a81942e14c8b67cc61a6"}, - {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0c4fc2741e0513b5d5a12fe200d6785bbcc621f6f2278893a9ca7bed7f2efb7d"}, - {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fc34fdd458ff77a2a00e3c86f899911f6f269d393ca5675842a6e92eea565bae"}, - {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8751f9c1442624da391bbd92bd4b072def6d7702a9390e4479f45c182392ff78"}, - {file = "pyzmq-25.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6581e886aec3135964a302a0f5eb68f964869b9efd1dbafdebceaaf2934f8a68"}, - {file = "pyzmq-25.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5482f08d2c3c42b920e8771ae8932fbaa0a67dff925fc476996ddd8155a170f3"}, - {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7fbcafa3ea16d1de1f213c226005fea21ee16ed56134b75b2dede5a2129e62"}, - {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:adecf6d02b1beab8d7c04bc36f22bb0e4c65a35eb0b4750b91693631d4081c70"}, - {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6d39e42a0aa888122d1beb8ec0d4ddfb6c6b45aecb5ba4013c27e2f28657765"}, - {file = "pyzmq-25.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7018289b402ebf2b2c06992813523de61d4ce17bd514c4339d8f27a6f6809492"}, - {file = "pyzmq-25.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9e68ae9864d260b18f311b68d29134d8776d82e7f5d75ce898b40a88df9db30f"}, - {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e21cc00e4debe8f54c3ed7b9fcca540f46eee12762a9fa56feb8512fd9057161"}, - {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f666ae327a6899ff560d741681fdcdf4506f990595201ed39b44278c471ad98"}, - {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f5efcc29056dfe95e9c9db0dfbb12b62db9c4ad302f812931b6d21dd04a9119"}, - {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:48e5e59e77c1a83162ab3c163fc01cd2eebc5b34560341a67421b09be0891287"}, - {file = "pyzmq-25.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:108c96ebbd573d929740d66e4c3d1bdf31d5cde003b8dc7811a3c8c5b0fc173b"}, - {file = "pyzmq-25.1.0.tar.gz", hash = "sha256:80c41023465d36280e801564a69cbfce8ae85ff79b080e1913f6e90481fb8957"}, + {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:381469297409c5adf9a0e884c5eb5186ed33137badcbbb0560b86e910a2f1e76"}, + {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:955215ed0604dac5b01907424dfa28b40f2b2292d6493445dd34d0dfa72586a8"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:985bbb1316192b98f32e25e7b9958088431d853ac63aca1d2c236f40afb17c83"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:afea96f64efa98df4da6958bae37f1cbea7932c35878b185e5982821bc883369"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76705c9325d72a81155bb6ab48d4312e0032bf045fb0754889133200f7a0d849"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:77a41c26205d2353a4c94d02be51d6cbdf63c06fbc1295ea57dad7e2d3381b71"}, + {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:12720a53e61c3b99d87262294e2b375c915fea93c31fc2336898c26d7aed34cd"}, + {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:57459b68e5cd85b0be8184382cefd91959cafe79ae019e6b1ae6e2ba8a12cda7"}, + {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:292fe3fc5ad4a75bc8df0dfaee7d0babe8b1f4ceb596437213821f761b4589f9"}, + {file = "pyzmq-25.1.1-cp310-cp310-win32.whl", hash = "sha256:35b5ab8c28978fbbb86ea54958cd89f5176ce747c1fb3d87356cf698048a7790"}, + {file = "pyzmq-25.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:11baebdd5fc5b475d484195e49bae2dc64b94a5208f7c89954e9e354fc609d8f"}, + {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:d20a0ddb3e989e8807d83225a27e5c2eb2260eaa851532086e9e0fa0d5287d83"}, + {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e1c1be77bc5fb77d923850f82e55a928f8638f64a61f00ff18a67c7404faf008"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d89528b4943d27029a2818f847c10c2cecc79fa9590f3cb1860459a5be7933eb"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90f26dc6d5f241ba358bef79be9ce06de58d477ca8485e3291675436d3827cf8"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2b92812bd214018e50b6380ea3ac0c8bb01ac07fcc14c5f86a5bb25e74026e9"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:2f957ce63d13c28730f7fd6b72333814221c84ca2421298f66e5143f81c9f91f"}, + {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:047a640f5c9c6ade7b1cc6680a0e28c9dd5a0825135acbd3569cc96ea00b2505"}, + {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7f7e58effd14b641c5e4dec8c7dab02fb67a13df90329e61c869b9cc607ef752"}, + {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c2910967e6ab16bf6fbeb1f771c89a7050947221ae12a5b0b60f3bca2ee19bca"}, + {file = "pyzmq-25.1.1-cp311-cp311-win32.whl", hash = "sha256:76c1c8efb3ca3a1818b837aea423ff8a07bbf7aafe9f2f6582b61a0458b1a329"}, + {file = "pyzmq-25.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:44e58a0554b21fc662f2712814a746635ed668d0fbc98b7cb9d74cb798d202e6"}, + {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:e1ffa1c924e8c72778b9ccd386a7067cddf626884fd8277f503c48bb5f51c762"}, + {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1af379b33ef33757224da93e9da62e6471cf4a66d10078cf32bae8127d3d0d4a"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cff084c6933680d1f8b2f3b4ff5bbb88538a4aac00d199ac13f49d0698727ecb"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2400a94f7dd9cb20cd012951a0cbf8249e3d554c63a9c0cdfd5cbb6c01d2dec"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d81f1ddae3858b8299d1da72dd7d19dd36aab654c19671aa8a7e7fb02f6638a"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:255ca2b219f9e5a3a9ef3081512e1358bd4760ce77828e1028b818ff5610b87b"}, + {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a882ac0a351288dd18ecae3326b8a49d10c61a68b01419f3a0b9a306190baf69"}, + {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:724c292bb26365659fc434e9567b3f1adbdb5e8d640c936ed901f49e03e5d32e"}, + {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ca1ed0bb2d850aa8471387882247c68f1e62a4af0ce9c8a1dbe0d2bf69e41fb"}, + {file = "pyzmq-25.1.1-cp312-cp312-win32.whl", hash = "sha256:b3451108ab861040754fa5208bca4a5496c65875710f76789a9ad27c801a0075"}, + {file = "pyzmq-25.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:eadbefd5e92ef8a345f0525b5cfd01cf4e4cc651a2cffb8f23c0dd184975d787"}, + {file = "pyzmq-25.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:db0b2af416ba735c6304c47f75d348f498b92952f5e3e8bff449336d2728795d"}, + {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c133e93b405eb0d36fa430c94185bdd13c36204a8635470cccc200723c13bb"}, + {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:273bc3959bcbff3f48606b28229b4721716598d76b5aaea2b4a9d0ab454ec062"}, + {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cbc8df5c6a88ba5ae385d8930da02201165408dde8d8322072e3e5ddd4f68e22"}, + {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:18d43df3f2302d836f2a56f17e5663e398416e9dd74b205b179065e61f1a6edf"}, + {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:73461eed88a88c866656e08f89299720a38cb4e9d34ae6bf5df6f71102570f2e"}, + {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:34c850ce7976d19ebe7b9d4b9bb8c9dfc7aac336c0958e2651b88cbd46682123"}, + {file = "pyzmq-25.1.1-cp36-cp36m-win32.whl", hash = "sha256:d2045d6d9439a0078f2a34b57c7b18c4a6aef0bee37f22e4ec9f32456c852c71"}, + {file = "pyzmq-25.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:458dea649f2f02a0b244ae6aef8dc29325a2810aa26b07af8374dc2a9faf57e3"}, + {file = "pyzmq-25.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7cff25c5b315e63b07a36f0c2bab32c58eafbe57d0dce61b614ef4c76058c115"}, + {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1579413ae492b05de5a6174574f8c44c2b9b122a42015c5292afa4be2507f28"}, + {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3d0a409d3b28607cc427aa5c30a6f1e4452cc44e311f843e05edb28ab5e36da0"}, + {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21eb4e609a154a57c520e3d5bfa0d97e49b6872ea057b7c85257b11e78068222"}, + {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:034239843541ef7a1aee0c7b2cb7f6aafffb005ede965ae9cbd49d5ff4ff73cf"}, + {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f8115e303280ba09f3898194791a153862cbf9eef722ad8f7f741987ee2a97c7"}, + {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1a5d26fe8f32f137e784f768143728438877d69a586ddeaad898558dc971a5ae"}, + {file = "pyzmq-25.1.1-cp37-cp37m-win32.whl", hash = "sha256:f32260e556a983bc5c7ed588d04c942c9a8f9c2e99213fec11a031e316874c7e"}, + {file = "pyzmq-25.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:abf34e43c531bbb510ae7e8f5b2b1f2a8ab93219510e2b287a944432fad135f3"}, + {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:87e34f31ca8f168c56d6fbf99692cc8d3b445abb5bfd08c229ae992d7547a92a"}, + {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c9c6c9b2c2f80747a98f34ef491c4d7b1a8d4853937bb1492774992a120f475d"}, + {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5619f3f5a4db5dbb572b095ea3cb5cc035335159d9da950830c9c4db2fbb6995"}, + {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a34d2395073ef862b4032343cf0c32a712f3ab49d7ec4f42c9661e0294d106f"}, + {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f0e6b78220aba09815cd1f3a32b9c7cb3e02cb846d1cfc526b6595f6046618"}, + {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3669cf8ee3520c2f13b2e0351c41fea919852b220988d2049249db10046a7afb"}, + {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2d163a18819277e49911f7461567bda923461c50b19d169a062536fffe7cd9d2"}, + {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:df27ffddff4190667d40de7beba4a950b5ce78fe28a7dcc41d6f8a700a80a3c0"}, + {file = "pyzmq-25.1.1-cp38-cp38-win32.whl", hash = "sha256:a382372898a07479bd34bda781008e4a954ed8750f17891e794521c3e21c2e1c"}, + {file = "pyzmq-25.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:52533489f28d62eb1258a965f2aba28a82aa747202c8fa5a1c7a43b5db0e85c1"}, + {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:03b3f49b57264909aacd0741892f2aecf2f51fb053e7d8ac6767f6c700832f45"}, + {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:330f9e188d0d89080cde66dc7470f57d1926ff2fb5576227f14d5be7ab30b9fa"}, + {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2ca57a5be0389f2a65e6d3bb2962a971688cbdd30b4c0bd188c99e39c234f414"}, + {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d457aed310f2670f59cc5b57dcfced452aeeed77f9da2b9763616bd57e4dbaae"}, + {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c56d748ea50215abef7030c72b60dd723ed5b5c7e65e7bc2504e77843631c1a6"}, + {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8f03d3f0d01cb5a018debeb412441996a517b11c5c17ab2001aa0597c6d6882c"}, + {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:820c4a08195a681252f46926de10e29b6bbf3e17b30037bd4250d72dd3ddaab8"}, + {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17ef5f01d25b67ca8f98120d5fa1d21efe9611604e8eb03a5147360f517dd1e2"}, + {file = "pyzmq-25.1.1-cp39-cp39-win32.whl", hash = "sha256:04ccbed567171579ec2cebb9c8a3e30801723c575601f9a990ab25bcac6b51e2"}, + {file = "pyzmq-25.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:e61f091c3ba0c3578411ef505992d356a812fb200643eab27f4f70eed34a29ef"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ade6d25bb29c4555d718ac6d1443a7386595528c33d6b133b258f65f963bb0f6"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0c95ddd4f6e9fca4e9e3afaa4f9df8552f0ba5d1004e89ef0a68e1f1f9807c7"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48e466162a24daf86f6b5ca72444d2bf39a5e58da5f96370078be67c67adc978"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abc719161780932c4e11aaebb203be3d6acc6b38d2f26c0f523b5b59d2fc1996"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ccf825981640b8c34ae54231b7ed00271822ea1c6d8ba1090ebd4943759abf5"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c2f20ce161ebdb0091a10c9ca0372e023ce24980d0e1f810f519da6f79c60800"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:deee9ca4727f53464daf089536e68b13e6104e84a37820a88b0a057b97bba2d2"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aa8d6cdc8b8aa19ceb319aaa2b660cdaccc533ec477eeb1309e2a291eaacc43a"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019e59ef5c5256a2c7378f2fb8560fc2a9ff1d315755204295b2eab96b254d0a"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b9af3757495c1ee3b5c4e945c1df7be95562277c6e5bccc20a39aec50f826cd0"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:548d6482dc8aadbe7e79d1b5806585c8120bafa1ef841167bc9090522b610fa6"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:057e824b2aae50accc0f9a0570998adc021b372478a921506fddd6c02e60308e"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2243700cc5548cff20963f0ca92d3e5e436394375ab8a354bbea2b12911b20b0"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79986f3b4af059777111409ee517da24a529bdbd46da578b33f25580adcff728"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:11d58723d44d6ed4dd677c5615b2ffb19d5c426636345567d6af82be4dff8a55"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:49d238cf4b69652257db66d0c623cd3e09b5d2e9576b56bc067a396133a00d4a"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fedbdc753827cf014c01dbbee9c3be17e5a208dcd1bf8641ce2cd29580d1f0d4"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc16ac425cc927d0a57d242589f87ee093884ea4804c05a13834d07c20db203c"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11c1d2aed9079c6b0c9550a7257a836b4a637feb334904610f06d70eb44c56d2"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e8a701123029cc240cea61dd2d16ad57cab4691804143ce80ecd9286b464d180"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:61706a6b6c24bdece85ff177fec393545a3191eeda35b07aaa1458a027ad1304"}, + {file = "pyzmq-25.1.1.tar.gz", hash = "sha256:259c22485b71abacdfa8bf79720cd7bcf4b9d128b30ea554f01ae71fdbfdaa23"}, ] [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "referencing" +version = "0.30.2" +description = "JSON Referencing + Python" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, + {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "requests" version = "2.31.0" @@ -2596,6 +2591,113 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] +[[package]] +name = "rpds-py" +version = "0.9.2" +description = "Python bindings to Rust's persistent data structures (rpds)" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"}, + {file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f"}, + {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f"}, + {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe"}, + {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6"}, + {file = "rpds_py-0.9.2-cp310-none-win32.whl", hash = "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764"}, + {file = "rpds_py-0.9.2-cp310-none-win_amd64.whl", hash = "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e"}, + {file = "rpds_py-0.9.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3"}, + {file = "rpds_py-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d"}, + {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c"}, + {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae"}, + {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de"}, + {file = "rpds_py-0.9.2-cp311-none-win32.whl", hash = "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab"}, + {file = "rpds_py-0.9.2-cp311-none-win_amd64.whl", hash = "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298"}, + {file = "rpds_py-0.9.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386"}, + {file = "rpds_py-0.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1"}, + {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b"}, + {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90"}, + {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d"}, + {file = "rpds_py-0.9.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d"}, + {file = "rpds_py-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55"}, + {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d"}, + {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32"}, + {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e"}, + {file = "rpds_py-0.9.2-cp38-none-win32.whl", hash = "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920"}, + {file = "rpds_py-0.9.2-cp38-none-win_amd64.whl", hash = "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044"}, + {file = "rpds_py-0.9.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260"}, + {file = "rpds_py-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324"}, + {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3"}, + {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535"}, + {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26"}, + {file = "rpds_py-0.9.2-cp39-none-win32.whl", hash = "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0"}, + {file = "rpds_py-0.9.2-cp39-none-win_amd64.whl", hash = "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"}, + {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"}, +] + [[package]] name = "scipy" version = "1.10.1" @@ -2858,53 +2960,50 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "1.4.48" +version = "1.4.49" description = "Database Abstraction Library" category = "main" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "SQLAlchemy-1.4.48-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:4bac3aa3c3d8bc7408097e6fe8bf983caa6e9491c5d2e2488cfcfd8106f13b6a"}, - {file = "SQLAlchemy-1.4.48-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:dbcae0e528d755f4522cad5842f0942e54b578d79f21a692c44d91352ea6d64e"}, - {file = "SQLAlchemy-1.4.48-cp27-cp27m-win32.whl", hash = "sha256:cbbe8b8bffb199b225d2fe3804421b7b43a0d49983f81dc654d0431d2f855543"}, - {file = "SQLAlchemy-1.4.48-cp27-cp27m-win_amd64.whl", hash = "sha256:627e04a5d54bd50628fc8734d5fc6df2a1aa5962f219c44aad50b00a6cdcf965"}, - {file = "SQLAlchemy-1.4.48-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9af1db7a287ef86e0f5cd990b38da6bd9328de739d17e8864f1817710da2d217"}, - {file = "SQLAlchemy-1.4.48-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:ce7915eecc9c14a93b73f4e1c9d779ca43e955b43ddf1e21df154184f39748e5"}, - {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5381ddd09a99638f429f4cbe1b71b025bed318f6a7b23e11d65f3eed5e181c33"}, - {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:87609f6d4e81a941a17e61a4c19fee57f795e96f834c4f0a30cee725fc3f81d9"}, - {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb0808ad34167f394fea21bd4587fc62f3bd81bba232a1e7fbdfa17e6cfa7cd7"}, - {file = "SQLAlchemy-1.4.48-cp310-cp310-win32.whl", hash = "sha256:d53cd8bc582da5c1c8c86b6acc4ef42e20985c57d0ebc906445989df566c5603"}, - {file = "SQLAlchemy-1.4.48-cp310-cp310-win_amd64.whl", hash = "sha256:4355e5915844afdc5cf22ec29fba1010166e35dd94a21305f49020022167556b"}, - {file = "SQLAlchemy-1.4.48-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:066c2b0413e8cb980e6d46bf9d35ca83be81c20af688fedaef01450b06e4aa5e"}, - {file = "SQLAlchemy-1.4.48-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c99bf13e07140601d111a7c6f1fc1519914dd4e5228315bbda255e08412f61a4"}, - {file = "SQLAlchemy-1.4.48-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ee26276f12614d47cc07bc85490a70f559cba965fb178b1c45d46ffa8d73fda"}, - {file = "SQLAlchemy-1.4.48-cp311-cp311-win32.whl", hash = "sha256:49c312bcff4728bffc6fb5e5318b8020ed5c8b958a06800f91859fe9633ca20e"}, - {file = "SQLAlchemy-1.4.48-cp311-cp311-win_amd64.whl", hash = "sha256:cef2e2abc06eab187a533ec3e1067a71d7bbec69e582401afdf6d8cad4ba3515"}, - {file = "SQLAlchemy-1.4.48-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:3509159e050bd6d24189ec7af373359f07aed690db91909c131e5068176c5a5d"}, - {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc2ab4d9f6d9218a5caa4121bdcf1125303482a1cdcfcdbd8567be8518969c0"}, - {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1ddbbcef9bcedaa370c03771ebec7e39e3944782bef49e69430383c376a250b"}, - {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f82d8efea1ca92b24f51d3aea1a82897ed2409868a0af04247c8c1e4fef5890"}, - {file = "SQLAlchemy-1.4.48-cp36-cp36m-win32.whl", hash = "sha256:e3e98d4907805b07743b583a99ecc58bf8807ecb6985576d82d5e8ae103b5272"}, - {file = "SQLAlchemy-1.4.48-cp36-cp36m-win_amd64.whl", hash = "sha256:25887b4f716e085a1c5162f130b852f84e18d2633942c8ca40dfb8519367c14f"}, - {file = "SQLAlchemy-1.4.48-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:0817c181271b0ce5df1aa20949f0a9e2426830fed5ecdcc8db449618f12c2730"}, - {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe1dd2562313dd9fe1778ed56739ad5d9aae10f9f43d9f4cf81d65b0c85168bb"}, - {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:68413aead943883b341b2b77acd7a7fe2377c34d82e64d1840860247cec7ff7c"}, - {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbde5642104ac6e95f96e8ad6d18d9382aa20672008cf26068fe36f3004491df"}, - {file = "SQLAlchemy-1.4.48-cp37-cp37m-win32.whl", hash = "sha256:11c6b1de720f816c22d6ad3bbfa2f026f89c7b78a5c4ffafb220e0183956a92a"}, - {file = "SQLAlchemy-1.4.48-cp37-cp37m-win_amd64.whl", hash = "sha256:eb5464ee8d4bb6549d368b578e9529d3c43265007193597ddca71c1bae6174e6"}, - {file = "SQLAlchemy-1.4.48-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:92e6133cf337c42bfee03ca08c62ba0f2d9695618c8abc14a564f47503157be9"}, - {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d29a3fc6d9c45962476b470a81983dd8add6ad26fdbfae6d463b509d5adcda"}, - {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:005e942b451cad5285015481ae4e557ff4154dde327840ba91b9ac379be3b6ce"}, - {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c8cfe951ed074ba5e708ed29c45397a95c4143255b0d022c7c8331a75ae61f3"}, - {file = "SQLAlchemy-1.4.48-cp38-cp38-win32.whl", hash = "sha256:2b9af65cc58726129d8414fc1a1a650dcdd594ba12e9c97909f1f57d48e393d3"}, - {file = "SQLAlchemy-1.4.48-cp38-cp38-win_amd64.whl", hash = "sha256:2b562e9d1e59be7833edf28b0968f156683d57cabd2137d8121806f38a9d58f4"}, - {file = "SQLAlchemy-1.4.48-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:a1fc046756cf2a37d7277c93278566ddf8be135c6a58397b4c940abf837011f4"}, - {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d9b55252d2ca42a09bcd10a697fa041e696def9dfab0b78c0aaea1485551a08"}, - {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6dab89874e72a9ab5462997846d4c760cdb957958be27b03b49cf0de5e5c327c"}, - {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd8b5ee5a3acc4371f820934b36f8109ce604ee73cc668c724abb054cebcb6e"}, - {file = "SQLAlchemy-1.4.48-cp39-cp39-win32.whl", hash = "sha256:eee09350fd538e29cfe3a496ec6f148504d2da40dbf52adefb0d2f8e4d38ccc4"}, - {file = "SQLAlchemy-1.4.48-cp39-cp39-win_amd64.whl", hash = "sha256:7ad2b0f6520ed5038e795cc2852eb5c1f20fa6831d73301ced4aafbe3a10e1f6"}, - {file = "SQLAlchemy-1.4.48.tar.gz", hash = "sha256:b47bc287096d989a0838ce96f7d8e966914a24da877ed41a7531d44b55cdb8df"}, + {file = "SQLAlchemy-1.4.49-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e126cf98b7fd38f1e33c64484406b78e937b1a280e078ef558b95bf5b6895f6"}, + {file = "SQLAlchemy-1.4.49-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:03db81b89fe7ef3857b4a00b63dedd632d6183d4ea5a31c5d8a92e000a41fc71"}, + {file = "SQLAlchemy-1.4.49-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:95b9df9afd680b7a3b13b38adf6e3a38995da5e162cc7524ef08e3be4e5ed3e1"}, + {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a63e43bf3f668c11bb0444ce6e809c1227b8f067ca1068898f3008a273f52b09"}, + {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f835c050ebaa4e48b18403bed2c0fda986525896efd76c245bdd4db995e51a4c"}, + {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c21b172dfb22e0db303ff6419451f0cac891d2e911bb9fbf8003d717f1bcf91"}, + {file = "SQLAlchemy-1.4.49-cp310-cp310-win32.whl", hash = "sha256:5fb1ebdfc8373b5a291485757bd6431de8d7ed42c27439f543c81f6c8febd729"}, + {file = "SQLAlchemy-1.4.49-cp310-cp310-win_amd64.whl", hash = "sha256:f8a65990c9c490f4651b5c02abccc9f113a7f56fa482031ac8cb88b70bc8ccaa"}, + {file = "SQLAlchemy-1.4.49-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8923dfdf24d5aa8a3adb59723f54118dd4fe62cf59ed0d0d65d940579c1170a4"}, + {file = "SQLAlchemy-1.4.49-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9ab2c507a7a439f13ca4499db6d3f50423d1d65dc9b5ed897e70941d9e135b0"}, + {file = "SQLAlchemy-1.4.49-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5debe7d49b8acf1f3035317e63d9ec8d5e4d904c6e75a2a9246a119f5f2fdf3d"}, + {file = "SQLAlchemy-1.4.49-cp311-cp311-win32.whl", hash = "sha256:82b08e82da3756765c2e75f327b9bf6b0f043c9c3925fb95fb51e1567fa4ee87"}, + {file = "SQLAlchemy-1.4.49-cp311-cp311-win_amd64.whl", hash = "sha256:171e04eeb5d1c0d96a544caf982621a1711d078dbc5c96f11d6469169bd003f1"}, + {file = "SQLAlchemy-1.4.49-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:36e58f8c4fe43984384e3fbe6341ac99b6b4e083de2fe838f0fdb91cebe9e9cb"}, + {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b31e67ff419013f99ad6f8fc73ee19ea31585e1e9fe773744c0f3ce58c039c30"}, + {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c14b29d9e1529f99efd550cd04dbb6db6ba5d690abb96d52de2bff4ed518bc95"}, + {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c40f3470e084d31247aea228aa1c39bbc0904c2b9ccbf5d3cfa2ea2dac06f26d"}, + {file = "SQLAlchemy-1.4.49-cp36-cp36m-win32.whl", hash = "sha256:706bfa02157b97c136547c406f263e4c6274a7b061b3eb9742915dd774bbc264"}, + {file = "SQLAlchemy-1.4.49-cp36-cp36m-win_amd64.whl", hash = "sha256:a7f7b5c07ae5c0cfd24c2db86071fb2a3d947da7bd487e359cc91e67ac1c6d2e"}, + {file = "SQLAlchemy-1.4.49-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:4afbbf5ef41ac18e02c8dc1f86c04b22b7a2125f2a030e25bbb4aff31abb224b"}, + {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24e300c0c2147484a002b175f4e1361f102e82c345bf263242f0449672a4bccf"}, + {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:201de072b818f8ad55c80d18d1a788729cccf9be6d9dc3b9d8613b053cd4836d"}, + {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653ed6817c710d0c95558232aba799307d14ae084cc9b1f4c389157ec50df5c"}, + {file = "SQLAlchemy-1.4.49-cp37-cp37m-win32.whl", hash = "sha256:647e0b309cb4512b1f1b78471fdaf72921b6fa6e750b9f891e09c6e2f0e5326f"}, + {file = "SQLAlchemy-1.4.49-cp37-cp37m-win_amd64.whl", hash = "sha256:ab73ed1a05ff539afc4a7f8cf371764cdf79768ecb7d2ec691e3ff89abbc541e"}, + {file = "SQLAlchemy-1.4.49-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:37ce517c011560d68f1ffb28af65d7e06f873f191eb3a73af5671e9c3fada08a"}, + {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1878ce508edea4a879015ab5215546c444233881301e97ca16fe251e89f1c55"}, + {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e8e608983e6f85d0852ca61f97e521b62e67969e6e640fe6c6b575d4db68557"}, + {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccf956da45290df6e809ea12c54c02ace7f8ff4d765d6d3dfb3655ee876ce58d"}, + {file = "SQLAlchemy-1.4.49-cp38-cp38-win32.whl", hash = "sha256:f167c8175ab908ce48bd6550679cc6ea20ae169379e73c7720a28f89e53aa532"}, + {file = "SQLAlchemy-1.4.49-cp38-cp38-win_amd64.whl", hash = "sha256:45806315aae81a0c202752558f0df52b42d11dd7ba0097bf71e253b4215f34f4"}, + {file = "SQLAlchemy-1.4.49-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:b6d0c4b15d65087738a6e22e0ff461b407533ff65a73b818089efc8eb2b3e1de"}, + {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a843e34abfd4c797018fd8d00ffffa99fd5184c421f190b6ca99def4087689bd"}, + {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1c890421651b45a681181301b3497e4d57c0d01dc001e10438a40e9a9c25ee77"}, + {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d26f280b8f0a8f497bc10573849ad6dc62e671d2468826e5c748d04ed9e670d5"}, + {file = "SQLAlchemy-1.4.49-cp39-cp39-win32.whl", hash = "sha256:ec2268de67f73b43320383947e74700e95c6770d0c68c4e615e9897e46296294"}, + {file = "SQLAlchemy-1.4.49-cp39-cp39-win_amd64.whl", hash = "sha256:bbdf16372859b8ed3f4d05f925a984771cd2abd18bd187042f24be4886c2a15f"}, + {file = "SQLAlchemy-1.4.49.tar.gz", hash = "sha256:06ff25cbae30c396c4b7737464f2a7fc37a67b7da409993b182b024cec80aed9"}, ] [package.dependencies] @@ -2984,35 +3083,35 @@ files = [ [[package]] name = "tomlkit" -version = "0.11.8" +version = "0.12.1" description = "Style preserving TOML library" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, - {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, + {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, + {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, ] [[package]] name = "tornado" -version = "6.3.2" +version = "6.3.3" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "dev" optional = false python-versions = ">= 3.8" files = [ - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, - {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, - {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, - {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, + {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, + {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, + {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, ] [[package]] @@ -3033,26 +3132,26 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typing-extensions" -version = "4.6.3" +version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.6.3-py3-none-any.whl", hash = "sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26"}, - {file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"}, + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] [[package]] name = "urllib3" -version = "2.0.3" +version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"}, - {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"}, + {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, + {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, ] [package.extras] @@ -3063,24 +3162,24 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.23.0" +version = "20.24.3" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"}, - {file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"}, + {file = "virtualenv-20.24.3-py3-none-any.whl", hash = "sha256:95a6e9398b4967fbcb5fef2acec5efaf9aa4972049d9ae41f95e0972a683fd02"}, + {file = "virtualenv-20.24.3.tar.gz", hash = "sha256:e5c3b4ce817b0b328af041506a2a299418c98747c4b1e68cb7527e74ced23efc"}, ] [package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.11,<4" -platformdirs = ">=3.2,<4" +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<4" [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "wcwidth" @@ -3204,19 +3303,19 @@ files = [ [[package]] name = "zipp" -version = "3.15.0" +version = "3.16.2" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, + {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, + {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [extras] box = ["click", "rich"] @@ -3225,4 +3324,4 @@ mark = ["banana-hep", "matplotlib", "pandas", "sqlalchemy"] [metadata] lock-version = "2.0" python-versions = "^3.8,<3.12" -content-hash = "1b953c2ab9f1d4629f923a290a9db0b092ce2ff711b2e6009372cf1d602d5da3" +content-hash = "223b56c91574c33cd1f4b6b74a6bde4002d72ab471ef8f90dc6d453b4936756e" diff --git a/pyproject.toml b/pyproject.toml index 31be6cb0c..ac9192de3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ PyYAML = "^6.0" lz4 = "^4.0.2" numba = "^0.57.0" # ekomark -banana-hep = { version = "^0.6.9", optional = true } +banana-hep = { version = "^0.6.10", optional = true } sqlalchemy = { version = "^1.4.21", optional = true } pandas = { version = "^1.3.0", optional = true } matplotlib = { version = "^3.5.1", optional = true } From a49fca63858f9e7101e8dc1a40a63e54606e9e20 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 12 Jan 2024 16:40:44 +0200 Subject: [PATCH 51/67] Fix evol_pdf --- src/ekobox/evol_pdf.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ekobox/evol_pdf.py b/src/ekobox/evol_pdf.py index 94c8e416c..4310a0eda 100644 --- a/src/ekobox/evol_pdf.py +++ b/src/ekobox/evol_pdf.py @@ -60,12 +60,16 @@ def evolve_pdfs( # apply PDF to eko evolved_PDF_list = [] + q2block_per_nf = {} with EKO.read(eko_path) as eko_output: for initial_PDF in initial_PDF_list: evolved_PDF_list.append( apply.apply_pdf(eko_output, initial_PDF, targetgrid) ) + # separate by nf the evolgrid (and order per nf/q) + q2block_per_nf = regroup_evolgrid(eko_output.evolgrid) # pylint: disable=E1101 + # update info file if targetgrid is None: targetgrid = operators_card.xgrid @@ -80,9 +84,6 @@ def evolve_pdfs( info_update=info_update, ) - # separate by nf the evolgrid (and order per nf/q) - q2block_per_nf = regroup_evolgrid(eko_output.evolgrid) - # write all replicas all_member_blocks = [] for evolved_PDF in evolved_PDF_list: From 7bf06e2ffaa0cdb892004e29cb838d40b9786bbc Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 15 Jul 2024 16:08:38 +0300 Subject: [PATCH 52/67] Fix outdated sc tests --- tests/eko/scale_variations/test_diff.py | 4 +--- tests/eko/scale_variations/test_expanded.py | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/eko/scale_variations/test_diff.py b/tests/eko/scale_variations/test_diff.py index c0dd67236..6c169e3bd 100644 --- a/tests/eko/scale_variations/test_diff.py +++ b/tests/eko/scale_variations/test_diff.py @@ -27,9 +27,7 @@ def compute_a_s(q2, order): couplings=CouplingsInfo( alphas=0.1181, alphaem=0.007496, - scale=91.00, - max_num_flavs=4, - num_flavs_ref=4, + ref=(91.00, 4), ), order=order, method=CouplingEvolutionMethod.EXPANDED, diff --git a/tests/eko/scale_variations/test_expanded.py b/tests/eko/scale_variations/test_expanded.py index 6af22dd51..be14e45a6 100644 --- a/tests/eko/scale_variations/test_expanded.py +++ b/tests/eko/scale_variations/test_expanded.py @@ -18,9 +18,7 @@ def compute_a_s(q2, order): couplings=CouplingsInfo( alphas=0.1181, alphaem=0.007496, - scale=91.00, - max_num_flavs=4, - num_flavs_ref=4, + ref=(91.00, 4), ), order=order, method=CouplingEvolutionMethod.EXPANDED, From 618639b606b1a7aa93276dcc1fd9e87c51c51ba1 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 15 Jul 2024 16:12:20 +0300 Subject: [PATCH 53/67] Appease black --- src/ekomark/data/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ekomark/data/__init__.py b/src/ekomark/data/__init__.py index b6242845b..89fb6377b 100644 --- a/src/ekomark/data/__init__.py +++ b/src/ekomark/data/__init__.py @@ -1,4 +1,5 @@ """EKO database configuration.""" + from typing import Union from eko.io.runcards import Legacy, OperatorCard, TheoryCard From 6b004dba87d494415a71a78535c65fbe32b7c142 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 19 Jul 2024 14:37:54 +0300 Subject: [PATCH 54/67] Make add SV to ModeMixin name --- src/eko/evolution_operator/__init__.py | 2 +- src/eko/evolution_operator/__init__.py.patch | 8 ++++---- src/eko/evolution_operator/grid.py | 2 +- src/eko/scale_variations/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 1c759c5c5..16aa4bb5b 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -600,7 +600,7 @@ def quad_ker_qed( return ker -class Operator(sv.ModeMixin): +class Operator(sv.ScaleVariationModeMixin): """Internal representation of a single EKO. The actual matrices are computed upon calling :meth:`compute`. diff --git a/src/eko/evolution_operator/__init__.py.patch b/src/eko/evolution_operator/__init__.py.patch index a3bc24ec1..58c3f74fd 100644 --- a/src/eko/evolution_operator/__init__.py.patch +++ b/src/eko/evolution_operator/__init__.py.patch @@ -534,10 +534,10 @@ index 1c759c5c..5eb394d0 100644 - return ker - - - class Operator(sv.ModeMixin): + class Operator(sv.ScaleVariationModeMixin): """Internal representation of a single EKO. -@@ -780,50 +282,6 @@ class Operator(sv.ModeMixin): +@@ -780,50 +282,6 @@ class Operator(sv.ScaleVariationModeMixin): labels.extend(br.singlet_unified_labels) return labels @@ -588,7 +588,7 @@ index 1c759c5c..5eb394d0 100644 def initialize_op_members(self): """Init all operators with the identity or zeros.""" eye = OpMember( -@@ -846,10 +304,7 @@ class Operator(sv.ModeMixin): +@@ -846,10 +304,7 @@ class Operator(sv.ScaleVariationModeMixin): else: self.op_members[n] = zero.copy() @@ -600,7 +600,7 @@ index 1c759c5c..5eb394d0 100644 """Run the integration for each grid point. Parameters -@@ -864,18 +319,56 @@ class Operator(sv.ModeMixin): +@@ -864,18 +319,56 @@ class Operator(sv.ScaleVariationModeMixin): """ column = [] k, logx = log_grid diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index e64885418..2539c3fc7 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -29,7 +29,7 @@ """In particular, only the ``operator`` and ``error`` fields are expected.""" -class OperatorGrid(sv.ModeMixin): +class OperatorGrid(sv.ScaleVariationModeMixin): """Collection of evolution operators for several scales. The operator grid is the driver class of the evolution. diff --git a/src/eko/scale_variations/__init__.py b/src/eko/scale_variations/__init__.py index 4af80592b..9c43f1f9c 100644 --- a/src/eko/scale_variations/__init__.py +++ b/src/eko/scale_variations/__init__.py @@ -36,7 +36,7 @@ def sv_mode(s): return Modes.unvaried -class ModeMixin: +class ScaleVariationModeMixin: """Mixin to cast scale variation mode.""" @property From 7a6c1cc2c42bd63a42ad2e4bae4d362cd4daafb7 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 19 Jul 2024 15:15:12 +0300 Subject: [PATCH 55/67] Introduce EvoMethods --- src/eko/evolution_operator/__init__.py | 6 +++++ src/eko/kernels/__init__.py | 32 ++++++++++++++++++++++++++ src/eko/scale_variations/__init__.py | 13 ++++++----- tests/eko/kernels/test_init.py | 21 +++++++++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 tests/eko/kernels/test_init.py diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 16aa4bb5b..8cd5829bd 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -20,6 +20,7 @@ from .. import basis_rotation as br from .. import interpolation, mellin from .. import scale_variations as sv +from ..kernels import ev_method from ..kernels import non_singlet as ns from ..kernels import non_singlet_qed as qed_ns from ..kernels import singlet as s @@ -780,6 +781,11 @@ def labels(self): labels.extend(br.singlet_unified_labels) return labels + @property + def ev_method(self): + """Return the evolution method.""" + return ev_method(self.config["method"]) + def quad_ker(self, label, logx, areas): """Return partially initialized integrand function. diff --git a/src/eko/kernels/__init__.py b/src/eko/kernels/__init__.py index 7640727b5..a10998b23 100644 --- a/src/eko/kernels/__init__.py +++ b/src/eko/kernels/__init__.py @@ -1 +1,33 @@ """The solutions to the |DGLAP| equations.""" + +import enum + + +class EvoMethods(enum.IntEnum): + """Enumerate evolution methods.""" + + ITERATE_EXACT = enum.auto() + ITERATE_EXPANDED = enum.auto() + PERTURBATIVE_EXACT = enum.auto() + PERTURBATIVE_EXPANDED = enum.auto() + TRUNCATED = enum.auto() + ORDERED_TRUNCATED = enum.auto() + DECOMPOSE_EXACT = enum.auto() + DECOMPOSE_EXPANDED = enum.auto() + + +def ev_method(s: EvoMethods) -> EvoMethods: + """Return the evolution methods. + + Parameters + ---------- + s : + string representation + + Returns + ------- + i : + int representation + + """ + return EvoMethods[s.value.upper().replace("-", "_")] diff --git a/src/eko/scale_variations/__init__.py b/src/eko/scale_variations/__init__.py index 9c43f1f9c..21d56a503 100644 --- a/src/eko/scale_variations/__init__.py +++ b/src/eko/scale_variations/__init__.py @@ -6,29 +6,30 @@ import enum +from ..io.types import ScaleVariationsMethod from . import expanded, exponentiated class Modes(enum.IntEnum): - """Enumerate scale Variation modes.""" + """Enumerate scale variation modes.""" unvaried = enum.auto() exponentiated = enum.auto() expanded = enum.auto() -def sv_mode(s): +def sv_mode(s: ScaleVariationsMethod) -> Modes: """Return the scale variation mode. Parameters ---------- - s : str + s : string representation Returns ------- - enum.IntEnum - enum representation + i : + int representation """ if s is not None: @@ -40,6 +41,6 @@ class ScaleVariationModeMixin: """Mixin to cast scale variation mode.""" @property - def sv_mode(self): + def sv_mode(self) -> Modes: """Return the scale variation mode.""" return sv_mode(self.config["ModSV"]) diff --git a/tests/eko/kernels/test_init.py b/tests/eko/kernels/test_init.py new file mode 100644 index 000000000..3717de275 --- /dev/null +++ b/tests/eko/kernels/test_init.py @@ -0,0 +1,21 @@ +from eko.io.types import EvolutionMethod +from eko.kernels import EvoMethods, ev_method + + +def test_ev_method(): + methods = { + "iterate-expanded": EvoMethods.ITERATE_EXPANDED, + "decompose-expanded": EvoMethods.DECOMPOSE_EXPANDED, + "perturbative-expanded": EvoMethods.PERTURBATIVE_EXPANDED, + "truncated": EvoMethods.TRUNCATED, + "ordered-truncated": EvoMethods.ORDERED_TRUNCATED, + "iterate-exact": EvoMethods.ITERATE_EXACT, + "decompose-exact": EvoMethods.DECOMPOSE_EXACT, + "perturbative-exact": EvoMethods.PERTURBATIVE_EXACT, + } + assert len(methods.keys()) == len(EvolutionMethod) + assert len(methods.keys()) == len(EvoMethods) + for s, i in methods.items(): + j = ev_method(EvolutionMethod(s)) + assert j == i + assert isinstance(j, int) From 5636b4a7e2e14f83ca0f5e34a24f71b53042e026 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 19 Jul 2024 15:45:25 +0300 Subject: [PATCH 56/67] Use EvoMethods in kernels --- src/eko/kernels/non_singlet.py | 27 ++++++------ src/eko/kernels/non_singlet_qed.py | 4 +- src/eko/kernels/singlet.py | 19 +++++---- src/eko/kernels/singlet_qed.py | 7 ++-- src/eko/kernels/valence_qed.py | 5 ++- tests/eko/kernels/test_kernels_QEDns.py | 3 +- tests/eko/kernels/test_kernels_QEDsinglet.py | 12 +++++- tests/eko/kernels/test_kernels_QEDvalence.py | 16 +++++-- tests/eko/kernels/test_ns.py | 32 ++++++-------- tests/eko/kernels/test_s.py | 44 ++++++++------------ 10 files changed, 87 insertions(+), 82 deletions(-) diff --git a/src/eko/kernels/non_singlet.py b/src/eko/kernels/non_singlet.py index bd5bd10f0..15b913438 100644 --- a/src/eko/kernels/non_singlet.py +++ b/src/eko/kernels/non_singlet.py @@ -4,6 +4,7 @@ import numpy as np from .. import beta +from . import EvoMethods from . import as4_evolution_integrals as as4_ei from . import evolution_integrals as ei @@ -355,7 +356,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbation order - method : str + method : int method gamma_ns : numpy.ndarray non-singlet anomalous dimensions @@ -378,38 +379,38 @@ def dispatcher( # use always exact in LO if order[0] == 1: return lo_exact(gamma_ns, a1, a0, betalist) - if method == "ordered-truncated": + if method is EvoMethods.ORDERED_TRUNCATED: return eko_ordered_truncated( gamma_ns, a1, a0, betalist, order, ev_op_iterations ) - if method == "truncated": + if method is EvoMethods.TRUNCATED: return eko_truncated(gamma_ns, a1, a0, betalist, order, ev_op_iterations) # NLO if order[0] == 2: if method in [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", + EvoMethods.ITERATE_EXPANDED, + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.PERTURBATIVE_EXPANDED, ]: return nlo_expanded(gamma_ns, a1, a0, betalist) - # if method in ["iterate-exact", "decompose-exact", "perturbative-exact"]: + # exact is left return nlo_exact(gamma_ns, a1, a0, betalist) # NNLO if order[0] == 3: if method in [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", + EvoMethods.ITERATE_EXPANDED, + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.PERTURBATIVE_EXPANDED, ]: return nnlo_expanded(gamma_ns, a1, a0, betalist) return nnlo_exact(gamma_ns, a1, a0, betalist) # N3LO if order[0] == 4: if method in [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", + EvoMethods.ITERATE_EXPANDED, + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.PERTURBATIVE_EXPANDED, ]: return n3lo_expanded(gamma_ns, a1, a0, betalist) return n3lo_exact(gamma_ns, a1, a0, betalist) diff --git a/src/eko/kernels/non_singlet_qed.py b/src/eko/kernels/non_singlet_qed.py index 7a2de816a..d81d5076b 100644 --- a/src/eko/kernels/non_singlet_qed.py +++ b/src/eko/kernels/non_singlet_qed.py @@ -146,7 +146,7 @@ def as4_exact(gamma_ns, a1, a0, beta): @nb.njit(cache=True) def dispatcher( order, - method, + _method, gamma_ns, as_list, aem_half, @@ -164,7 +164,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbation order - method : str + method : int method gamma_ns : numpy.ndarray non-singlet anomalous dimensions diff --git a/src/eko/kernels/singlet.py b/src/eko/kernels/singlet.py index 5983c0c67..e637af046 100644 --- a/src/eko/kernels/singlet.py +++ b/src/eko/kernels/singlet.py @@ -6,6 +6,7 @@ from ekore import anomalous_dimensions as ad from .. import beta +from . import EvoMethods from . import as4_evolution_integrals as as4_ei from . import evolution_integrals as ei @@ -579,7 +580,7 @@ def dispatcher( # pylint: disable=too-many-return-statements ---------- order : tuple(int,int) perturbative order - method : str + method : int method gamma_singlet : numpy.ndarray singlet anomalous dimensions matrices @@ -609,9 +610,9 @@ def dispatcher( # pylint: disable=too-many-return-statements return lo_exact(gamma_singlet, a1, a0, betalist) # Common method for NLO and NNLO - if method in ["iterate-exact", "iterate-expanded"]: + if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: return eko_iterate(gamma_singlet, a1, a0, betalist, order, ev_op_iterations) - if method == "perturbative-exact": + if method is EvoMethods.PERTURBATIVE_EXACT: return eko_perturbative( gamma_singlet, a1, @@ -622,7 +623,7 @@ def dispatcher( # pylint: disable=too-many-return-statements ev_op_max_order, True, ) - if method == "perturbative-expanded": + if method is EvoMethods.PERTURBATIVE_EXPANDED: return eko_perturbative( gamma_singlet, a1, @@ -633,19 +634,19 @@ def dispatcher( # pylint: disable=too-many-return-statements ev_op_max_order, False, ) - if method in ["truncated", "ordered-truncated"]: + if method in [EvoMethods.TRUNCATED, EvoMethods.ORDERED_TRUNCATED]: return eko_truncated(gamma_singlet, a1, a0, betalist, order, ev_op_iterations) # These methods are scattered for nlo and nnlo - if method == "decompose-exact": + if method is EvoMethods.DECOMPOSE_EXACT: if order[0] == 2: return nlo_decompose_exact(gamma_singlet, a1, a0, betalist) - elif order[0] == 3: + if order[0] == 3: return nnlo_decompose_exact(gamma_singlet, a1, a0, betalist) return n3lo_decompose_exact(gamma_singlet, a1, a0, nf) - if method == "decompose-expanded": + if method is EvoMethods.DECOMPOSE_EXPANDED: if order[0] == 2: return nlo_decompose_expanded(gamma_singlet, a1, a0, betalist) - elif order[0] == 3: + if order[0] == 3: return nnlo_decompose_expanded(gamma_singlet, a1, a0, betalist) return n3lo_decompose_expanded(gamma_singlet, a1, a0, nf) raise NotImplementedError("Selected method is not implemented") diff --git a/src/eko/kernels/singlet_qed.py b/src/eko/kernels/singlet_qed.py index c13dee95c..2f2ba8eee 100644 --- a/src/eko/kernels/singlet_qed.py +++ b/src/eko/kernels/singlet_qed.py @@ -6,6 +6,7 @@ from ekore import anomalous_dimensions as ad from .. import beta +from . import EvoMethods @nb.njit(cache=True) @@ -66,7 +67,7 @@ def dispatcher( a_half, nf, ev_op_iterations, - ev_op_max_order, + _ev_op_max_order, ): """Determine used kernel and call it. @@ -74,7 +75,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbative order - method : str + method : int method gamma_singlet : numpy.ndarray singlet anomalous dimensions matrices @@ -96,7 +97,7 @@ def dispatcher( e_s : numpy.ndarray singlet EKO """ - if method in ["iterate-exact", "iterate-expanded"]: + if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: return eko_iterate( gamma_singlet, as_list, a_half, nf, order, ev_op_iterations, 4 ) diff --git a/src/eko/kernels/valence_qed.py b/src/eko/kernels/valence_qed.py index 0d5b747c3..074dd95ed 100644 --- a/src/eko/kernels/valence_qed.py +++ b/src/eko/kernels/valence_qed.py @@ -2,6 +2,7 @@ import numba as nb +from . import EvoMethods from .singlet_qed import eko_iterate @@ -14,7 +15,7 @@ def dispatcher( a_half, nf, ev_op_iterations, - ev_op_max_order, + _ev_op_max_order, ): """ Determine used kernel and call it. @@ -45,7 +46,7 @@ def dispatcher( e_v : numpy.ndarray singlet EKO """ - if method in ["iterate-exact", "iterate-expanded"]: + if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: return eko_iterate( gamma_valence, as_list, a_half, nf, order, ev_op_iterations, 2 ) diff --git a/tests/eko/kernels/test_kernels_QEDns.py b/tests/eko/kernels/test_kernels_QEDns.py index bb18c3e17..9fce3097b 100644 --- a/tests/eko/kernels/test_kernels_QEDns.py +++ b/tests/eko/kernels/test_kernels_QEDns.py @@ -3,6 +3,7 @@ from eko import basis_rotation as br from eko.couplings import Couplings +from eko.kernels import EvoMethods from eko.kernels import non_singlet_qed as ns from eko.quantities.couplings import CouplingEvolutionMethod, CouplingsInfo from eko.quantities.heavy_quarks import QuarkMassScheme @@ -14,7 +15,7 @@ # "perturbative-expanded", # "truncated", # "ordered-truncated", - "iterate-exact", + EvoMethods.ITERATE_EXACT, # "decompose-exact", # "perturbative-exact", ] diff --git a/tests/eko/kernels/test_kernels_QEDsinglet.py b/tests/eko/kernels/test_kernels_QEDsinglet.py index b953c053c..2fee4e17f 100644 --- a/tests/eko/kernels/test_kernels_QEDsinglet.py +++ b/tests/eko/kernels/test_kernels_QEDsinglet.py @@ -1,6 +1,7 @@ import numpy as np import pytest +from eko.kernels import EvoMethods from eko.kernels import singlet_qed as s from ekore.anomalous_dimensions.unpolarized import space_like as ad @@ -10,7 +11,7 @@ # "perturbative-expanded", # "truncated", # "ordered-truncated", - "iterate-exact", + EvoMethods.ITERATE_EXACT, # "decompose-exact", # "perturbative-exact", ] @@ -125,5 +126,12 @@ def test_zero_true_gamma(monkeypatch): def test_error(): with pytest.raises(NotImplementedError): s.dispatcher( - (3, 2), "AAA", np.random.rand(4, 3, 2, 2), [0.2, 0.1], [0.01], 3, 10, 10 + (3, 2), + "iterate-exact", + np.random.rand(4, 3, 2, 2), + [0.2, 0.1], + [0.01], + 3, + 10, + 10, ) diff --git a/tests/eko/kernels/test_kernels_QEDvalence.py b/tests/eko/kernels/test_kernels_QEDvalence.py index 29f0f3d7a..4b12a492b 100644 --- a/tests/eko/kernels/test_kernels_QEDvalence.py +++ b/tests/eko/kernels/test_kernels_QEDvalence.py @@ -1,6 +1,7 @@ import numpy as np import pytest +from eko.kernels import EvoMethods from eko.kernels import valence_qed as val from ekore import anomalous_dimensions @@ -10,13 +11,13 @@ # "perturbative-expanded", # "truncated", # "ordered-truncated", - "iterate-exact", + EvoMethods.ITERATE_EXACT, # "decompose-exact", # "perturbative-exact", ] -def test_zero(monkeypatch): +def test_zero(): """No evolution results in exp(0)""" nf = 3 ev_op_iterations = 2 @@ -57,7 +58,7 @@ def test_zero(monkeypatch): ) -def test_zero_true_gamma(monkeypatch): +def test_zero_true_gamma(): """No evolution results in exp(0)""" nf = 3 ev_op_iterations = 2 @@ -101,5 +102,12 @@ def test_zero_true_gamma(monkeypatch): def test_error(): with pytest.raises(NotImplementedError): val.dispatcher( - (3, 2), "AAA", np.random.rand(4, 3, 2, 2), [0.2, 0.1], [0.01], 3, 10, 10 + (3, 2), + "iterate-exact", + np.random.rand(4, 3, 2, 2), + [0.2, 0.1], + [0.01], + 3, + 10, + 10, ) diff --git a/tests/eko/kernels/test_ns.py b/tests/eko/kernels/test_ns.py index f78282142..70e7faf8d 100644 --- a/tests/eko/kernels/test_ns.py +++ b/tests/eko/kernels/test_ns.py @@ -5,19 +5,9 @@ import ekore.anomalous_dimensions.unpolarized.space_like as ad from eko import beta +from eko.kernels import EvoMethods from eko.kernels import non_singlet as ns -methods = [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", - "truncated", - "ordered-truncated", - "iterate-exact", - "decompose-exact", - "perturbative-exact", -] - def test_zero(): """No evolution results in exp(0)""" @@ -25,7 +15,7 @@ def test_zero(): ev_op_iterations = 2 gamma_ns = np.array([1 + 0.0j, 1 + 0j, 1 + 0j, 1 + 0j]) for order in [1, 2, 3, 4]: - for method in methods: + for method in EvoMethods: np.testing.assert_allclose( ns.dispatcher( (order, 0), method, gamma_ns, 1.0, 1.0, nf, ev_op_iterations @@ -54,7 +44,7 @@ def test_ode_lo(): a0 = 0.3 for a1 in [0.1, 0.2]: r = a1 * gamma_ns / (beta.beta_qcd((2, 0), nf) * a1**2) - for method in methods: + for method in EvoMethods: rhs = r * ns.dispatcher( (1, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -91,7 +81,7 @@ def test_ode_nlo(): r = (a1 * gamma_ns[0] + a1**2 * gamma_ns[1]) / ( beta.beta_qcd((2, 0), nf) * a1**2 + beta.beta_qcd((3, 0), nf) * a1**3 ) - for method in ["iterate-exact"]: + for method in [EvoMethods.ITERATE_EXACT]: rhs = r * ns.dispatcher( (2, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -130,7 +120,7 @@ def test_ode_nnlo(): + beta.beta_qcd((3, 0), nf) * a1**2 + beta.beta_qcd((4, 0), nf) * a1**3 ) - for method in ["iterate-exact"]: + for method in [EvoMethods.ITERATE_EXACT]: rhs = r * ns.dispatcher( (3, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -172,7 +162,7 @@ def test_ode_n3lo(): + beta.beta_qcd((4, 0), nf) * a1**3 + beta.beta_qcd((5, 0), nf) * a1**4 ) - for method in ["iterate-exact"]: + for method in [EvoMethods.ITERATE_EXACT]: rhs = r * ns.dispatcher( (4, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -202,7 +192,9 @@ def test_ode_n3lo(): def test_error(monkeypatch): monkeypatch.setattr("eko.beta.beta_qcd", lambda *_args: 1.0) with pytest.raises(NotImplementedError, match="order is not implemented"): - ns.dispatcher((5, 0), "iterate-exact", np.random.rand(3) + 0j, 0.2, 0.1, 3, 10) + ns.dispatcher( + (5, 0), EvoMethods.ITERATE_EXACT, np.random.rand(3) + 0j, 0.2, 0.1, 3, 10 + ) with pytest.raises(NotImplementedError): ad.gamma_ns((2, 0), 10202, 1, (0, 0, 0, 0, 0, 0, 0), 3) @@ -216,7 +208,7 @@ def test_gamma_usage(): gamma_ns = np.full(4, np.nan) for order in range(1, 5): gamma_ns[order - 1] = np.random.rand() - for method in methods: + for method in EvoMethods: r = ns.dispatcher( (order, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -225,8 +217,8 @@ def test_gamma_usage(): for order in range(1, 5): gamma_ns = np.random.rand(order) gamma_ns[order - 1] = np.nan - for method in methods: - if method == "ordered-truncated": + for method in EvoMethods: + if method is EvoMethods.ORDERED_TRUNCATED: # we are actually dividing by a np.nan, # since the sum of U vec is nan warnings.simplefilter("ignore", RuntimeWarning) diff --git a/tests/eko/kernels/test_s.py b/tests/eko/kernels/test_s.py index 5380ba319..ff4fdfc0d 100644 --- a/tests/eko/kernels/test_s.py +++ b/tests/eko/kernels/test_s.py @@ -3,20 +3,10 @@ import numpy as np import pytest +from eko.kernels import EvoMethods from eko.kernels import singlet as s from ekore import anomalous_dimensions as ad -methods = [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", - "truncated", - "ordered-truncated", - "iterate-exact", - "decompose-exact", - "perturbative-exact", -] - def test_zero_lo(monkeypatch): """No evolution results in exp(0)""" @@ -35,7 +25,7 @@ def test_zero_lo(monkeypatch): np.array([[0, 0], [0, 1]]), ), ) - for method in methods: + for method in EvoMethods: np.testing.assert_allclose( s.dispatcher( (1, 0), method, gamma_s, 1, 1, nf, ev_op_iterations, ev_op_max_order @@ -75,8 +65,8 @@ def test_zero_nlo_decompose(monkeypatch): ), ) for method in [ - "decompose-expanded", - "decompose-exact", + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.DECOMPOSE_EXACT, ]: np.testing.assert_allclose( s.dispatcher( @@ -117,8 +107,8 @@ def test_zero_nnlo_decompose(monkeypatch): ), ) for method in [ - "decompose-expanded", - "decompose-exact", + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.DECOMPOSE_EXACT, ]: np.testing.assert_allclose( s.dispatcher( @@ -159,8 +149,8 @@ def test_zero_n3lo_decompose(monkeypatch): ), ) for method in [ - "decompose-expanded", - "decompose-exact", + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.DECOMPOSE_EXACT, ]: np.testing.assert_allclose( s.dispatcher( @@ -200,7 +190,7 @@ def test_similarity(): ]: ref = s.dispatcher( order, - "decompose-exact", + EvoMethods.DECOMPOSE_EXACT, gamma_s, a1, a0, @@ -208,7 +198,7 @@ def test_similarity(): ev_op_iterations, ev_op_max_order, ) - for method in methods: + for method in EvoMethods: np.testing.assert_allclose( s.dispatcher( order, @@ -227,7 +217,9 @@ def test_similarity(): def test_error(): with pytest.raises(NotImplementedError): - s.dispatcher((4, 0), "AAA", np.random.rand(3, 2, 2), 0.2, 0.1, 3, 10, 10) + s.dispatcher( + (4, 0), "iterate-exact", np.random.rand(3, 2, 2), 0.2, 0.1, 3, 10, 10 + ) def mk_almost_diag_matrix(n, max_ang=np.pi / 8.0): @@ -247,7 +239,7 @@ def test_gamma_usage(): gamma_s = np.full((4, 2, 2), np.nan) for order in range(1, 5): gamma_s[order - 1] = mk_almost_diag_matrix(1) - for method in methods: + for method in EvoMethods: r = s.dispatcher( (order, 0), method, @@ -263,8 +255,8 @@ def test_gamma_usage(): for order in range(1, 5): gamma_s = mk_almost_diag_matrix(4) gamma_s[order - 1] = np.full((2, 2), np.nan) - for method in methods: - if "iterate" in method: + for method in EvoMethods: + if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: # we are actually dividing by the determinant of # matrix full of np.nan warnings.simplefilter("ignore", RuntimeWarning) @@ -287,8 +279,8 @@ def test_singlet_back(): nf = 4 a1 = 3.0 a0 = 4.0 - s10 = s.dispatcher(order, "iterate-exact", gamma_s, a1, a0, nf, 15, 1) + s10 = s.dispatcher(order, EvoMethods.ITERATE_EXACT, gamma_s, a1, a0, nf, 15, 1) np.testing.assert_allclose( np.linalg.inv(s10), - s.dispatcher(order, "iterate-exact", gamma_s, a0, a1, nf, 15, 1), + s.dispatcher(order, EvoMethods.ITERATE_EXACT, gamma_s, a0, a1, nf, 15, 1), ) From db2ef3ed63894e806b78e4c0ff41281179a3ac64 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 19 Jul 2024 16:03:51 +0300 Subject: [PATCH 57/67] Use EvoMethods in ev_op --- src/eko/evolution_operator/__init__.py | 5 ++- tests/eko/evolution_operator/test_init.py | 43 ++++++++++++++------- tests/eko/scale_variations/test_diff.py | 4 +- tests/eko/scale_variations/test_expanded.py | 4 +- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 8cd5829bd..ec56b6db6 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -20,6 +20,7 @@ from .. import basis_rotation as br from .. import interpolation, mellin from .. import scale_variations as sv +from ..io.types import EvolutionMethod from ..kernels import ev_method from ..kernels import non_singlet as ns from ..kernels import non_singlet_qed as qed_ns @@ -784,7 +785,7 @@ def labels(self): @property def ev_method(self): """Return the evolution method.""" - return ev_method(self.config["method"]) + return ev_method(EvolutionMethod(self.config["method"])) def quad_ker(self, label, logx, areas): """Return partially initialized integrand function. @@ -809,7 +810,7 @@ def quad_ker(self, label, logx, areas): order=self.order, mode0=label[0], mode1=label[1], - method=self.config["method"], + method=self.ev_method, is_log=self.int_disp.log, logx=logx, areas=areas, diff --git a/tests/eko/evolution_operator/test_init.py b/tests/eko/evolution_operator/test_init.py index 597f645f8..23395f66b 100644 --- a/tests/eko/evolution_operator/test_init.py +++ b/tests/eko/evolution_operator/test_init.py @@ -11,6 +11,7 @@ from eko.evolution_operator import Operator, quad_ker from eko.interpolation import InterpolatorDispatcher from eko.io.runcards import OperatorCard, ScaleVariationsMethod, TheoryCard +from eko.kernels import EvoMethods from eko.kernels import non_singlet as ns from eko.kernels import non_singlet_qed as qed_ns from eko.kernels import singlet as s @@ -25,7 +26,7 @@ def test_quad_ker_errors(): order=(1, 0), mode0=mode0, mode1=0, - method="", + method="iterate-exact", is_log=True, logx=np.log(0.1), areas=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], @@ -60,15 +61,29 @@ def test_quad_ker(monkeypatch): monkeypatch.setattr(qed_ns, "dispatcher", lambda *args: 1.0) monkeypatch.setattr(s, "dispatcher", lambda *args: np.identity(2)) params = [ - ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.0, 0.0), - ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.123, 1.0), - ((3, 1), br.non_singlet_pids_map["ns+u"], 0, "", 0.0, 0.0), - ((1, 0), 100, 100, "", 0.123, 1.0), - ((1, 0), 100, 21, "", 0.0, 0.0), - ((1, 1), 100, 100, "iterate-exact", 0.123, 1.0), - ((1, 1), 100, 21, "iterate-exact", 0.123, 0.0), - ((1, 1), 10200, 10200, "iterate-exact", 0.123, 1.0), - ((1, 1), 10200, 10204, "iterate-exact", 0.123, 0.0), + ((1, 0), br.non_singlet_pids_map["ns+"], 0, EvoMethods.ITERATE_EXACT, 0.0, 0.0), + ( + (1, 0), + br.non_singlet_pids_map["ns+"], + 0, + EvoMethods.ITERATE_EXACT, + 0.123, + 1.0, + ), + ( + (3, 1), + br.non_singlet_pids_map["ns+u"], + 0, + EvoMethods.ITERATE_EXACT, + 0.0, + 0.0, + ), + ((1, 0), 100, 100, EvoMethods.ITERATE_EXACT, 0.123, 1.0), + ((1, 0), 100, 21, EvoMethods.ITERATE_EXACT, 0.0, 0.0), + ((1, 1), 100, 100, EvoMethods.ITERATE_EXACT, 0.123, 1.0), + ((1, 1), 100, 21, EvoMethods.ITERATE_EXACT, 0.123, 0.0), + ((1, 1), 10200, 10200, EvoMethods.ITERATE_EXACT, 0.123, 1.0), + ((1, 1), 10200, 10204, EvoMethods.ITERATE_EXACT, 0.123, 0.0), ] for order, mode0, mode1, method, logx, res in params: for is_log in [True, False]: @@ -107,7 +122,7 @@ def test_quad_ker(monkeypatch): order=(1, 0), mode0=label[0], mode1=label[1], - method="", + method=EvoMethods.ITERATE_EXACT, is_log=True, logx=0.123, areas=np.zeros(3), @@ -143,7 +158,7 @@ def test_quad_ker(monkeypatch): order=(1, 1), mode0=label[0], mode1=label[1], - method="iterate-exact", + method=EvoMethods.ITERATE_EXACT, is_log=True, logx=0.123, areas=np.zeros(3), @@ -171,7 +186,7 @@ def test_quad_ker(monkeypatch): order=(1, 0), mode0=br.non_singlet_pids_map["ns+"], mode1=0, - method="", + method=EvoMethods.ITERATE_EXACT, is_log=True, logx=0.0, areas=np.zeros(3), @@ -436,7 +451,7 @@ def quad_ker_pegasus( order = (2, 0) mode0 = br.non_singlet_pids_map["ns+"] mode1 = 0 - method = "" + method = EvoMethods.ITERATE_EXACT logxs = np.log(int_disp.xgrid.raw) a1 = 1 a0 = 2 diff --git a/tests/eko/scale_variations/test_diff.py b/tests/eko/scale_variations/test_diff.py index c0dd67236..8ade8bcac 100644 --- a/tests/eko/scale_variations/test_diff.py +++ b/tests/eko/scale_variations/test_diff.py @@ -11,7 +11,7 @@ from eko import basis_rotation as br from eko.beta import beta_qcd_as2, beta_qcd_as3 from eko.couplings import CouplingEvolutionMethod, Couplings, CouplingsInfo -from eko.kernels import non_singlet, singlet +from eko.kernels import EvoMethods, non_singlet, singlet from eko.quantities.heavy_quarks import QuarkMassScheme from eko.scale_variations import expanded, exponentiated from ekore.anomalous_dimensions.unpolarized.space_like import gamma_ns, gamma_singlet @@ -19,7 +19,7 @@ NF = 4 Q02 = 1.65**2 Q12 = 100**2 -EV_METHOD = "truncated" +EV_METHOD = EvoMethods.TRUNCATED def compute_a_s(q2, order): diff --git a/tests/eko/scale_variations/test_expanded.py b/tests/eko/scale_variations/test_expanded.py index 6af22dd51..bfacc1c96 100644 --- a/tests/eko/scale_variations/test_expanded.py +++ b/tests/eko/scale_variations/test_expanded.py @@ -2,7 +2,7 @@ from eko import basis_rotation as br from eko.couplings import CouplingEvolutionMethod, Couplings, CouplingsInfo -from eko.kernels import non_singlet, singlet +from eko.kernels import EvoMethods, non_singlet, singlet from eko.quantities.heavy_quarks import QuarkMassScheme from eko.scale_variations import Modes, expanded from ekore.anomalous_dimensions.unpolarized.space_like import gamma_ns, gamma_singlet @@ -10,7 +10,7 @@ NF = 4 Q02 = 1.65**2 Q12 = 100**2 -EV_METHOD = "truncated" +EV_METHOD = EvoMethods.TRUNCATED def compute_a_s(q2, order): From 1b1e4ce4b651033fc1c23c89cb79f42a03019c66 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 19 Jul 2024 16:41:12 +0300 Subject: [PATCH 58/67] Introduce BackwardsMethods --- .../operator_matrix_element.py | 50 ++++++++++++++++--- src/eko/kernels/__init__.py | 6 ++- tests/eko/evolution_operator/test_ome.py | 19 +++---- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 202fd18d9..b4b6731b4 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -1,6 +1,7 @@ """The |OME| for the non-trivial matching conditions in the |VFNS| evolution.""" import copy +import enum import functools import logging @@ -20,6 +21,33 @@ logger = logging.getLogger(__name__) +class BackwardsMethods(enum.IntEnum): + """Enumerate backward methods.""" + + FORWARD = enum.auto() + EXACT = enum.auto() + EXPANDED = enum.auto() + + +def bw_method(s: InversionMethod) -> BackwardsMethods: + """Return the backward method. + + Parameters + ---------- + s : + string representation + + Returns + ------- + i : + int representation + + """ + if s is not None: + return BackwardsMethods[s.value.upper()] + return BackwardsMethods.FORWARD + + @nb.njit(cache=True) def build_ome(A, matching_order, a_s, backward_method): r"""Construct the matching expansion in :math:`a_s` with the appropriate method. @@ -32,7 +60,7 @@ def build_ome(A, matching_order, a_s, backward_method): perturbation matching order a_s : float strong coupling, needed only for the exact inverse - backward_method : InversionMethod or None + backward_method : BackwardsMethods empty or method for inverting the matching condition (exact or expanded) Returns @@ -51,7 +79,7 @@ def build_ome(A, matching_order, a_s, backward_method): ome = np.eye(len(A[0]), dtype=np.complex_) A = A[:, :, :] A = np.ascontiguousarray(A) - if backward_method is InversionMethod.EXPANDED: + if backward_method is BackwardsMethods.EXPANDED: # expended inverse if matching_order[0] >= 1: ome -= a_s * A[0] @@ -68,7 +96,7 @@ def build_ome(A, matching_order, a_s, backward_method): if matching_order[0] >= 3: ome += a_s**3 * A[2] # need inverse exact ? so add the missing pieces - if backward_method is InversionMethod.EXACT: + if backward_method is BackwardsMethods.EXACT: ome = np.linalg.inv(ome) return ome @@ -216,7 +244,9 @@ class OperatorMatrixElement(Operator): def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): super().__init__(config, managers, Segment(q2, q2, nf)) - self.backward_method = config["backward_inversion"] if is_backward else None + self.backward_method = bw_method( + config["backward_inversion"] if is_backward else None + ) if is_backward: self.is_intrinsic = True else: @@ -241,7 +271,10 @@ def labels(self): logger.warning("%s: skipping non-singlet sector", self.log_label) else: labels.append((200, 200)) - if self.is_intrinsic or self.backward_method is not None: + if ( + self.is_intrinsic + or self.backward_method is not BackwardsMethods.FORWARD + ): # intrinsic labels, which are not zero at NLO labels.append((br.matching_hminus_pid, br.matching_hminus_pid)) # These contributions are always 0 for the moment @@ -257,7 +290,10 @@ def labels(self): (br.matching_hplus_pid, 100), ] ) - if self.is_intrinsic or self.backward_method is not None: + if ( + self.is_intrinsic + or self.backward_method is not BackwardsMethods.FORWARD + ): labels.extend( [ (21, br.matching_hplus_pid), @@ -329,7 +365,7 @@ def compute(self): self.log_label, self.order[0], self.order[1], - self.backward_method, + BackwardsMethods(self.backward_method).name, ) self.integrate() diff --git a/src/eko/kernels/__init__.py b/src/eko/kernels/__init__.py index a10998b23..594fbf1fa 100644 --- a/src/eko/kernels/__init__.py +++ b/src/eko/kernels/__init__.py @@ -2,6 +2,8 @@ import enum +from ..io.types import EvolutionMethod + class EvoMethods(enum.IntEnum): """Enumerate evolution methods.""" @@ -16,8 +18,8 @@ class EvoMethods(enum.IntEnum): DECOMPOSE_EXPANDED = enum.auto() -def ev_method(s: EvoMethods) -> EvoMethods: - """Return the evolution methods. +def ev_method(s: EvolutionMethod) -> EvoMethods: + """Return the evolution method. Parameters ---------- diff --git a/tests/eko/evolution_operator/test_ome.py b/tests/eko/evolution_operator/test_ome.py index b844290c9..584635967 100644 --- a/tests/eko/evolution_operator/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -8,6 +8,7 @@ from eko import interpolation, mellin from eko import scale_variations as sv from eko.evolution_operator.operator_matrix_element import ( + BackwardsMethods, OperatorMatrixElement, build_ome, quad_ker, @@ -33,7 +34,7 @@ def test_build_ome_as(): aS = A_singlet((o, 0), N, nf, L, is_msbar) for a in [aNS, aS]: - for method in [None, InversionMethod.EXPANDED, InversionMethod.EXACT]: + for method in BackwardsMethods: dim = len(a[0]) if o != 1: assert len(a) == o @@ -53,7 +54,7 @@ def test_build_ome_nlo(): aNSi = A_non_singlet((1, 0), N, nf, L) aSi = A_singlet((1, 0), N, nf, L, is_msbar) for a in [aNSi, aSi]: - for method in [None, InversionMethod.EXPANDED, InversionMethod.EXACT]: + for method in BackwardsMethods: dim = len(a[0]) # hh assert a[0, -1, -1] != 0.0 @@ -86,7 +87,7 @@ def test_quad_ker_errors(): is_log=True, logx=0.123, areas=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], - backward_method=None, + backward_method=BackwardsMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -119,7 +120,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.123, areas=np.zeros(3), - backward_method=None, + backward_method=BackwardsMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -138,7 +139,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.123, areas=np.zeros(3), - backward_method=None, + backward_method=BackwardsMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -157,7 +158,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.0, areas=np.zeros(3), - backward_method=None, + backward_method=BackwardsMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -191,7 +192,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.123, areas=np.zeros(3), - backward_method=InversionMethod.EXPANDED, + backward_method=BackwardsMethods.EXPANDED, a_s=0.0, nf=3, L=0.0, @@ -228,7 +229,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.123, areas=np.zeros(3), - backward_method=InversionMethod.EXACT, + backward_method=BackwardsMethods.EXACT, a_s=0.0, nf=3, L=0.0, @@ -252,7 +253,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.0, areas=np.array([0.01, 0.1, 1.0]), - backward_method=None, + backward_method=BackwardsMethods.FORWARD, a_s=0.0, nf=3, L=0.0, From c88627f71da3df6780692cbcc1bd04c37d0776ae Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 22 Jul 2024 13:23:45 +0300 Subject: [PATCH 59/67] Rename matching method --- .../operator_matrix_element.py | 34 ++++++++----------- src/ekomark/data/operators.py | 2 +- tests/eko/evolution_operator/test_ome.py | 20 +++++------ 3 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index b4b6731b4..cf6cbcb97 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -21,16 +21,16 @@ logger = logging.getLogger(__name__) -class BackwardsMethods(enum.IntEnum): +class MatchingMethods(enum.IntEnum): """Enumerate backward methods.""" FORWARD = enum.auto() - EXACT = enum.auto() - EXPANDED = enum.auto() + BACKWARD_EXACT = enum.auto() + BACKWARD_EXPANDED = enum.auto() -def bw_method(s: InversionMethod) -> BackwardsMethods: - """Return the backward method. +def matching_method(s: InversionMethod) -> MatchingMethods: + """Return the matching method. Parameters ---------- @@ -44,8 +44,8 @@ def bw_method(s: InversionMethod) -> BackwardsMethods: """ if s is not None: - return BackwardsMethods[s.value.upper()] - return BackwardsMethods.FORWARD + return MatchingMethods[s.value.upper()] + return MatchingMethods.FORWARD @nb.njit(cache=True) @@ -60,7 +60,7 @@ def build_ome(A, matching_order, a_s, backward_method): perturbation matching order a_s : float strong coupling, needed only for the exact inverse - backward_method : BackwardsMethods + backward_method : MatchingMethods empty or method for inverting the matching condition (exact or expanded) Returns @@ -79,7 +79,7 @@ def build_ome(A, matching_order, a_s, backward_method): ome = np.eye(len(A[0]), dtype=np.complex_) A = A[:, :, :] A = np.ascontiguousarray(A) - if backward_method is BackwardsMethods.EXPANDED: + if backward_method is MatchingMethods.BACKWARD_EXPANDED: # expended inverse if matching_order[0] >= 1: ome -= a_s * A[0] @@ -96,7 +96,7 @@ def build_ome(A, matching_order, a_s, backward_method): if matching_order[0] >= 3: ome += a_s**3 * A[2] # need inverse exact ? so add the missing pieces - if backward_method is BackwardsMethods.EXACT: + if backward_method is MatchingMethods.BACKWARD_EXACT: ome = np.linalg.inv(ome) return ome @@ -244,7 +244,7 @@ class OperatorMatrixElement(Operator): def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): super().__init__(config, managers, Segment(q2, q2, nf)) - self.backward_method = bw_method( + self.backward_method = matching_method( config["backward_inversion"] if is_backward else None ) if is_backward: @@ -271,10 +271,7 @@ def labels(self): logger.warning("%s: skipping non-singlet sector", self.log_label) else: labels.append((200, 200)) - if ( - self.is_intrinsic - or self.backward_method is not BackwardsMethods.FORWARD - ): + if self.is_intrinsic or self.backward_method is not MatchingMethods.FORWARD: # intrinsic labels, which are not zero at NLO labels.append((br.matching_hminus_pid, br.matching_hminus_pid)) # These contributions are always 0 for the moment @@ -290,10 +287,7 @@ def labels(self): (br.matching_hplus_pid, 100), ] ) - if ( - self.is_intrinsic - or self.backward_method is not BackwardsMethods.FORWARD - ): + if self.is_intrinsic or self.backward_method is not MatchingMethods.FORWARD: labels.extend( [ (21, br.matching_hplus_pid), @@ -365,7 +359,7 @@ def compute(self): self.log_label, self.order[0], self.order[1], - BackwardsMethods(self.backward_method).name, + MatchingMethods(self.backward_method).name, ) self.integrate() diff --git a/src/ekomark/data/operators.py b/src/ekomark/data/operators.py index ad928574d..03ad4d349 100644 --- a/src/ekomark/data/operators.py +++ b/src/ekomark/data/operators.py @@ -15,7 +15,7 @@ ev_op_max_order=10, ev_op_iterations=10, backward_inversion="expanded", - n_integration_cores=0, + n_integration_cores=1, debug_skip_non_singlet=False, debug_skip_singlet=False, mugrid=[10], diff --git a/tests/eko/evolution_operator/test_ome.py b/tests/eko/evolution_operator/test_ome.py index 584635967..553e5823c 100644 --- a/tests/eko/evolution_operator/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -8,7 +8,7 @@ from eko import interpolation, mellin from eko import scale_variations as sv from eko.evolution_operator.operator_matrix_element import ( - BackwardsMethods, + MatchingMethods, OperatorMatrixElement, build_ome, quad_ker, @@ -34,7 +34,7 @@ def test_build_ome_as(): aS = A_singlet((o, 0), N, nf, L, is_msbar) for a in [aNS, aS]: - for method in BackwardsMethods: + for method in MatchingMethods: dim = len(a[0]) if o != 1: assert len(a) == o @@ -54,7 +54,7 @@ def test_build_ome_nlo(): aNSi = A_non_singlet((1, 0), N, nf, L) aSi = A_singlet((1, 0), N, nf, L, is_msbar) for a in [aNSi, aSi]: - for method in BackwardsMethods: + for method in MatchingMethods: dim = len(a[0]) # hh assert a[0, -1, -1] != 0.0 @@ -87,7 +87,7 @@ def test_quad_ker_errors(): is_log=True, logx=0.123, areas=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], - backward_method=BackwardsMethods.FORWARD, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -120,7 +120,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.123, areas=np.zeros(3), - backward_method=BackwardsMethods.FORWARD, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -139,7 +139,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.123, areas=np.zeros(3), - backward_method=BackwardsMethods.FORWARD, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -158,7 +158,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.0, areas=np.zeros(3), - backward_method=BackwardsMethods.FORWARD, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -192,7 +192,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.123, areas=np.zeros(3), - backward_method=BackwardsMethods.EXPANDED, + backward_method=MatchingMethods.BACKWARD_EXPANDED, a_s=0.0, nf=3, L=0.0, @@ -229,7 +229,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.123, areas=np.zeros(3), - backward_method=BackwardsMethods.EXACT, + backward_method=MatchingMethods.BACKWARD_EXACT, a_s=0.0, nf=3, L=0.0, @@ -253,7 +253,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.0, areas=np.array([0.01, 0.1, 1.0]), - backward_method=BackwardsMethods.FORWARD, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, From d4a3f71889822f0311f342ec2d3ca97c049acf8f Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 22 Jul 2024 13:29:41 +0300 Subject: [PATCH 60/67] Fix MatchingMethods doc string --- src/eko/evolution_operator/operator_matrix_element.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index cf6cbcb97..87c76183a 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -22,7 +22,7 @@ class MatchingMethods(enum.IntEnum): - """Enumerate backward methods.""" + """Enumerate matching methods.""" FORWARD = enum.auto() BACKWARD_EXACT = enum.auto() From 7f079bc6001ac3f38d0d55ebd0a3cd271da7e976 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 22 Jul 2024 15:12:05 +0300 Subject: [PATCH 61/67] Fix matching renaming --- src/eko/evolution_operator/operator_matrix_element.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 87c76183a..25e5df2dd 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -44,7 +44,7 @@ def matching_method(s: InversionMethod) -> MatchingMethods: """ if s is not None: - return MatchingMethods[s.value.upper()] + return MatchingMethods["BACKWARD_" + s.value.upper()] return MatchingMethods.FORWARD From e40acaec28c4212d5a3ffb809ece959d415c2016 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 24 Jul 2024 15:10:40 +0300 Subject: [PATCH 62/67] Allow only iterate-exact for QED --- src/eko/kernels/singlet_qed.py | 2 +- src/eko/kernels/valence_qed.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/eko/kernels/singlet_qed.py b/src/eko/kernels/singlet_qed.py index 2f2ba8eee..d63a2f1ac 100644 --- a/src/eko/kernels/singlet_qed.py +++ b/src/eko/kernels/singlet_qed.py @@ -97,7 +97,7 @@ def dispatcher( e_s : numpy.ndarray singlet EKO """ - if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: + if method is EvoMethods.ITERATE_EXACT: return eko_iterate( gamma_singlet, as_list, a_half, nf, order, ev_op_iterations, 4 ) diff --git a/src/eko/kernels/valence_qed.py b/src/eko/kernels/valence_qed.py index 074dd95ed..186c70219 100644 --- a/src/eko/kernels/valence_qed.py +++ b/src/eko/kernels/valence_qed.py @@ -24,7 +24,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbative order - method : str + method : int method gamma_singlet : numpy.ndarray singlet anomalous dimensions matrices @@ -46,7 +46,7 @@ def dispatcher( e_v : numpy.ndarray singlet EKO """ - if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: + if method is EvoMethods.ITERATE_EXACT: return eko_iterate( gamma_valence, as_list, a_half, nf, order, ev_op_iterations, 2 ) From c92c3a24a0cd2cc440048f1028af9b98ab63b49a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 18:11:07 +0000 Subject: [PATCH 63/67] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.16.0 → v3.17.0](https://github.com/asottile/pyupgrade/compare/v3.16.0...v3.17.0) - [github.com/pre-commit/pre-commit: v3.7.1 → v3.8.0](https://github.com/pre-commit/pre-commit/compare/v3.7.1...v3.8.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 67e901972..d579fb856 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.17.0 hooks: - id: pyupgrade - repo: https://github.com/pycqa/pydocstyle @@ -53,6 +53,6 @@ repos: files: ^crates/.*\.rs$ args: [] - repo: https://github.com/pre-commit/pre-commit - rev: v3.7.1 + rev: v3.8.0 hooks: - id: validate_manifest From 48476f9f2a3ab8121ff694db7c413fbb3bdddf1c Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 8 Aug 2024 14:49:28 +0300 Subject: [PATCH 64/67] Fix Rust ev_op patch --- src/eko/evolution_operator/__init__.py.patch | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py.patch b/src/eko/evolution_operator/__init__.py.patch index 58c3f74fd..d8258ee14 100644 --- a/src/eko/evolution_operator/__init__.py.patch +++ b/src/eko/evolution_operator/__init__.py.patch @@ -1,5 +1,5 @@ diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py -index 1c759c5c..5eb394d0 100644 +index ec56b6db..374d0d0b 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -3,15 +3,15 @@ r"""Contains the central operator classes. @@ -20,7 +20,7 @@ index 1c759c5c..5eb394d0 100644 import ekore.anomalous_dimensions.polarized.space_like as ad_ps import ekore.anomalous_dimensions.unpolarized.space_like as ad_us -@@ -27,92 +27,10 @@ from ..kernels import singlet_qed as qed_s +@@ -29,92 +29,10 @@ from ..kernels import singlet_qed as qed_s from ..kernels import valence_qed as qed_v from ..matchings import Segment, lepton_number from ..member import OpMember @@ -114,7 +114,7 @@ index 1c759c5c..5eb394d0 100644 spec = [ ("is_singlet", nb.boolean), ("is_QEDsinglet", nb.boolean), -@@ -184,422 +102,6 @@ class QuadKerBase: +@@ -186,422 +104,6 @@ class QuadKerBase: return self.path.prefactor * pj * self.path.jac @@ -537,9 +537,9 @@ index 1c759c5c..5eb394d0 100644 class Operator(sv.ScaleVariationModeMixin): """Internal representation of a single EKO. -@@ -780,50 +282,6 @@ class Operator(sv.ScaleVariationModeMixin): - labels.extend(br.singlet_unified_labels) - return labels +@@ -787,50 +289,6 @@ class Operator(sv.ScaleVariationModeMixin): + """Return the evolution method.""" + return ev_method(EvolutionMethod(self.config["method"])) - def quad_ker(self, label, logx, areas): - """Return partially initialized integrand function. @@ -564,7 +564,7 @@ index 1c759c5c..5eb394d0 100644 - order=self.order, - mode0=label[0], - mode1=label[1], -- method=self.config["method"], +- method=self.ev_method, - is_log=self.int_disp.log, - logx=logx, - areas=areas, @@ -588,7 +588,7 @@ index 1c759c5c..5eb394d0 100644 def initialize_op_members(self): """Init all operators with the identity or zeros.""" eye = OpMember( -@@ -846,10 +304,7 @@ class Operator(sv.ScaleVariationModeMixin): +@@ -853,10 +311,7 @@ class Operator(sv.ScaleVariationModeMixin): else: self.op_members[n] = zero.copy() @@ -600,7 +600,7 @@ index 1c759c5c..5eb394d0 100644 """Run the integration for each grid point. Parameters -@@ -864,18 +319,56 @@ class Operator(sv.ScaleVariationModeMixin): +@@ -871,18 +326,56 @@ class Operator(sv.ScaleVariationModeMixin): """ column = [] k, logx = log_grid From b651ebe9699dc2ffcacd561e05bb52026e4d1944 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 8 Aug 2024 15:02:47 +0300 Subject: [PATCH 65/67] Fix Rust ev_op patch --- src/eko/evolution_operator/__init__.py.patch | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py.patch b/src/eko/evolution_operator/__init__.py.patch index 58c3f74fd..995d77b6b 100644 --- a/src/eko/evolution_operator/__init__.py.patch +++ b/src/eko/evolution_operator/__init__.py.patch @@ -1,8 +1,8 @@ diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py -index 1c759c5c..5eb394d0 100644 +index fe07ade9..0f58c9e5 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py -@@ -3,15 +3,15 @@ r"""Contains the central operator classes. +@@ -3,16 +3,16 @@ r"""Contains the central operator classes. See :doc:`Operator overview `. """ @@ -11,6 +11,7 @@ index 1c759c5c..5eb394d0 100644 import os import time from multiprocessing import Pool + from typing import Dict, Tuple +import ekors import numba as nb @@ -20,7 +21,7 @@ index 1c759c5c..5eb394d0 100644 import ekore.anomalous_dimensions.polarized.space_like as ad_ps import ekore.anomalous_dimensions.unpolarized.space_like as ad_us -@@ -27,92 +27,10 @@ from ..kernels import singlet_qed as qed_s +@@ -30,92 +30,10 @@ from ..kernels import singlet_qed as qed_s from ..kernels import valence_qed as qed_v from ..matchings import Segment, lepton_number from ..member import OpMember @@ -114,7 +115,7 @@ index 1c759c5c..5eb394d0 100644 spec = [ ("is_singlet", nb.boolean), ("is_QEDsinglet", nb.boolean), -@@ -184,422 +102,6 @@ class QuadKerBase: +@@ -187,421 +105,6 @@ class QuadKerBase: return self.path.prefactor * pj * self.path.jac @@ -533,13 +534,12 @@ index 1c759c5c..5eb394d0 100644 - ) - return ker - -- - class Operator(sv.ScaleVariationModeMixin): - """Internal representation of a single EKO. -@@ -780,50 +282,6 @@ class Operator(sv.ScaleVariationModeMixin): - labels.extend(br.singlet_unified_labels) - return labels + OpMembers = Dict[OperatorLabel, OpMember] + """Map of all operators.""" +@@ -792,50 +295,6 @@ class Operator(sv.ScaleVariationModeMixin): + """Return the evolution method.""" + return ev_method(EvolutionMethod(self.config["method"])) - def quad_ker(self, label, logx, areas): - """Return partially initialized integrand function. @@ -564,7 +564,7 @@ index 1c759c5c..5eb394d0 100644 - order=self.order, - mode0=label[0], - mode1=label[1], -- method=self.config["method"], +- method=self.ev_method, - is_log=self.int_disp.log, - logx=logx, - areas=areas, @@ -588,7 +588,7 @@ index 1c759c5c..5eb394d0 100644 def initialize_op_members(self): """Init all operators with the identity or zeros.""" eye = OpMember( -@@ -846,10 +304,7 @@ class Operator(sv.ScaleVariationModeMixin): +@@ -858,10 +317,7 @@ class Operator(sv.ScaleVariationModeMixin): else: self.op_members[n] = zero.copy() @@ -600,7 +600,7 @@ index 1c759c5c..5eb394d0 100644 """Run the integration for each grid point. Parameters -@@ -864,18 +319,56 @@ class Operator(sv.ScaleVariationModeMixin): +@@ -876,18 +332,56 @@ class Operator(sv.ScaleVariationModeMixin): """ column = [] k, logx = log_grid From 873853904bce8f3d5856d4c300f279c7f524a0df Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 9 Aug 2024 11:01:11 +0300 Subject: [PATCH 66/67] Merge master --- .github/workflows/crates.yml | 28 + .github/workflows/maturin.yml | 123 + .github/workflows/pypi.yml | 2 +- .github/workflows/unittests-rust.yml | 21 + .github/workflows/unittests.yml | 6 +- .pre-commit-config.yaml | 36 +- .readthedocs.yaml | 12 +- crates/Cargo.lock => Cargo.lock | 52 +- Cargo.toml | 22 + README.md | 1 + benchmarks/DSSV_bench.py | 1 + benchmarks/NNPDF_bench.py | 1 + benchmarks/apfel_bench.py | 2 +- benchmarks/asv.conf.json | 2 +- benchmarks/eko/benchmark_alphaem.py | 12 +- benchmarks/eko/benchmark_evol_to_unity.py | 8 +- benchmarks/eko/benchmark_inverse_matching.py | 9 +- benchmarks/eko/benchmark_msbar_evolution.py | 8 +- benchmarks/eko/benchmark_strong_coupling.py | 74 +- benchmarks/ekobox/benchmark_evol_pdf.py | 10 +- ...k_ad.py => benchmark_pegasus_ad_us_as2.py} | 40 +- benchmarks/ekore/benchmark_pegasus_mellin.py | 41 + .../ekore/benchmark_pegasus_ome_ps_as2.py | 199 + benchmarks/lha_paper_bench.py | 23 +- crates/Cargo.toml | 3 - crates/README.md | 18 + crates/bump-versions.py | 40 + crates/doc-header.html | 65 + crates/eko/Cargo.toml | 19 +- crates/eko/doc-header.html | 1 + crates/eko/pyproject.toml | 4 +- crates/eko/src/bib.rs | 1 + crates/eko/src/lib.rs | 31 +- crates/eko/src/mellin.rs | 20 +- crates/ekore/Cargo.toml | 17 +- crates/ekore/doc-header.html | 1 + crates/ekore/refs.bib | 19 + .../unpolarized/spacelike.rs | 33 +- .../unpolarized/spacelike/as2.rs | 338 ++ .../unpolarized/spacelike/as3.rs | 455 +++ crates/ekore/src/bib.rs | 30 +- crates/ekore/src/constants.rs | 26 +- crates/ekore/src/harmonics.rs | 6 +- crates/ekore/src/harmonics/cache.rs | 82 +- crates/ekore/src/harmonics/g_functions.rs | 50 + crates/ekore/src/harmonics/polygamma.rs | 15 +- crates/ekore/src/harmonics/w1.rs | 3 +- crates/ekore/src/harmonics/w2.rs | 13 + crates/ekore/src/harmonics/w3.rs | 13 + crates/ekore/src/harmonics/w4.rs | 13 + crates/ekore/src/util.rs | 20 + crates/make_bib.py | 23 +- crates/parse-abbrev.py | 20 + crates/release.json | 1 + doc/source/code/genpdf.rst | 56 +- doc/source/conf.py | 10 +- doc/source/overview/tutorials/alpha_s.ipynb | 17 +- doc/source/overview/tutorials/dglap.ipynb | 15 +- doc/source/overview/tutorials/output.ipynb | 8 +- doc/source/overview/tutorials/pdf.ipynb | 134 +- doc/source/refs.bib | 63 +- doc/source/theory/Matching.rst | 6 +- doc/source/theory/N3LO_ad.rst | 5 +- extras/lh_bench_23/.gitignore | 1 + extras/lh_bench_23/cfg.py | 16 +- extras/lh_bench_23/parse_to_latex.py | 179 + extras/lh_bench_23/plot_bench.py | 49 - extras/lh_bench_23/plot_bench_evol.py | 16 +- extras/lh_bench_23/plot_bench_msht.py | 57 +- extras/lh_bench_23/plot_trn_exa.py | 64 + extras/lh_bench_23/run-n3lo.py | 2 +- extras/lh_bench_23/run-nnlo.py | 3 +- extras/lh_bench_23/run-trn_exa.py | 72 + .../{run_fhmv.sh => run_fhmruvv.sh} | 8 +- extras/lh_bench_23/tables/EKO.zip | Bin 0 -> 742394 bytes extras/lh_bench_23/tables/MSHT.zip | Bin 0 -> 99712 bytes extras/lh_bench_23/tables/table14-part1.csv | 12 + extras/lh_bench_23/tables/table15-part1.csv | 12 + .../tables/table_FFNS-1_iterate-exact.csv | 12 + .../tables/table_FFNS-1_truncated.csv | 12 + .../tables/table_FFNS-2_iterate-exact.csv | 12 + .../tables/table_FFNS-2_truncated.csv | 12 + .../tables/table_FFNS-3_iterate-exact.csv | 12 + .../tables/table_FFNS-3_truncated.csv | 12 + extras/lh_bench_23/utils.py | 84 +- extras/n3lo_bench/plot_msht.py | 2 +- extras/n3lo_bench/splitting_function_utils.py | 4 +- flake.lock | 130 +- flake.nix | 62 +- poetry.lock | 3254 +++++++++-------- pyproject.toml | 24 +- pyproject.toml.patch | 16 +- rustify.sh | 8 +- src/eko/__init__.py | 1 + src/eko/couplings.py | 16 +- src/eko/evolution_operator/__init__.py | 69 +- src/eko/evolution_operator/__init__.py.patch | 70 +- src/eko/evolution_operator/flavors.py | 1 + src/eko/evolution_operator/grid.py | 49 +- .../evolution_operator/matching_condition.py | 50 +- .../operator_matrix_element.py | 74 +- src/eko/evolution_operator/physical.py | 24 +- src/eko/evolution_operator/quad_ker.py | 4 +- src/eko/gamma.py | 1 + src/eko/interpolation.py | 1 + src/eko/io/bases.py | 117 - src/eko/io/dictlike.py | 1 + src/eko/io/exceptions.py | 1 + src/eko/io/inventory.py | 5 +- src/eko/io/items.py | 1 + src/eko/io/legacy.py | 49 +- src/eko/io/manipulate.py | 234 +- src/eko/io/metadata.py | 9 +- src/eko/io/paths.py | 1 + src/eko/io/raw.py | 1 + src/eko/io/runcards.py | 56 +- src/eko/io/struct.py | 21 +- src/eko/io/types.py | 9 +- src/eko/kernels/__init__.py | 34 + src/eko/kernels/as4_evolution_integrals.py | 4 +- src/eko/kernels/non_singlet.py | 32 +- src/eko/kernels/non_singlet_qed.py | 8 +- src/eko/kernels/singlet.py | 26 +- src/eko/kernels/singlet_qed.py | 8 +- src/eko/kernels/utils.py | 26 - src/eko/kernels/valence_qed.py | 8 +- src/eko/matchings.py | 1 + src/eko/mellin.py | 7 +- src/eko/member.py | 1 + src/eko/msbar_masses.py | 7 +- src/eko/quantities/couplings.py | 15 +- src/eko/quantities/heavy_quarks.py | 19 +- src/eko/runner/__init__.py | 5 +- src/eko/runner/commons.py | 3 +- src/eko/runner/legacy.py | 11 +- src/eko/runner/managed.py | 3 +- src/eko/runner/operators.py | 5 +- src/eko/runner/parts.py | 55 +- src/eko/runner/recipes.py | 1 + src/eko/scale_variations/__init__.py | 19 +- src/eko/scale_variations/expanded.py | 8 +- src/eko/scale_variations/exponentiated.py | 1 + src/ekobox/apply.py | 65 +- src/ekobox/cards.py | 10 +- src/ekobox/cli/__init__.py | 1 + src/ekobox/cli/base.py | 1 + src/ekobox/cli/convert.py | 1 + src/ekobox/cli/inspect.py | 3 +- src/ekobox/cli/library.py | 1 + src/ekobox/cli/log.py | 1 + src/ekobox/cli/run.py | 15 +- src/ekobox/cli/runcards.py | 7 +- src/ekobox/evol_pdf.py | 36 +- src/ekobox/genpdf/__init__.py | 13 +- src/ekobox/genpdf/export.py | 1 + src/ekobox/genpdf/flavors.py | 1 + src/ekobox/genpdf/load.py | 1 + src/ekobox/info_file.py | 77 +- src/ekobox/mock.py | 1 + src/ekobox/utils.py | 16 +- src/ekomark/__init__.py | 1 + src/ekomark/benchmark/external/LHA_utils.py | 1 + src/ekomark/benchmark/external/apfel_utils.py | 1 + .../benchmark/external/lhapdf_utils.py | 1 + .../benchmark/external/pegasus_utils.py | 1 + src/ekomark/benchmark/runner.py | 14 +- src/ekomark/data/__init__.py | 29 + src/ekomark/data/operators.py | 3 +- src/ekomark/navigator/__init__.py | 1 + src/ekomark/navigator/glob.py | 1 + src/ekomark/navigator/navigator.py | 1 + src/ekomark/plots.py | 50 +- .../polarized/space_like/__init__.py | 1 + .../polarized/space_like/as2.py | 16 +- .../polarized/space_like/as3.py | 10 +- .../unpolarized/space_like/__init__.py | 2 + .../unpolarized/space_like/as2.py | 2 +- .../unpolarized/space_like/as3.py | 1 + .../unpolarized/space_like/as4/__init__.py | 1 + .../space_like/as4/fhmruvv/__init__.py | 1 + .../unpolarized/space_like/as4/fhmruvv/ggg.py | 1 + .../unpolarized/space_like/as4/fhmruvv/ggq.py | 132 +- .../space_like/as4/fhmruvv/gnsm.py | 1 + .../space_like/as4/fhmruvv/gnsp.py | 1 + .../space_like/as4/fhmruvv/gnsv.py | 1 + .../unpolarized/space_like/as4/fhmruvv/gps.py | 1 + .../unpolarized/space_like/as4/fhmruvv/gqg.py | 1 + .../unpolarized/space_like/as4/ggq.py | 89 +- .../unpolarized/space_like/as4/gnsm.py | 1 + .../unpolarized/space_like/as4/gnsp.py | 1 + .../unpolarized/space_like/as4/gnsv.py | 1 + .../unpolarized/time_like/__init__.py | 2 + .../unpolarized/time_like/as3.py | 2 +- src/ekore/harmonics/__init__.py | 1 + src/ekore/harmonics/cache.py | 1 + src/ekore/harmonics/g_functions.py | 1 + src/ekore/harmonics/log_functions.py | 1 + src/ekore/harmonics/w3.py | 3 +- src/ekore/harmonics/w4.py | 3 +- src/ekore/harmonics/w5.py | 3 +- .../polarized/space_like/as1.py | 1 + .../polarized/space_like/as2.py | 36 +- .../unpolarized/space_like/__init__.py | 4 +- .../unpolarized/space_like/as1.py | 12 +- .../unpolarized/space_like/as2.py | 37 +- .../unpolarized/space_like/as3/__init__.py | 16 +- .../unpolarized/space_like/as3/aHg.py | 5 +- .../unpolarized/space_like/as3/aHg_param.py | 1178 ++---- .../unpolarized/space_like/as3/aHq.py | 3 +- .../unpolarized/space_like/as3/agg.py | 99 +- .../unpolarized/space_like/as3/agq.py | 3 +- .../unpolarized/space_like/as3/aqg.py | 3 +- .../unpolarized/space_like/as3/aqqNS.py | 5 +- .../unpolarized/space_like/as3/aqqPS.py | 3 +- tests/eko/evolution_operator/test_grid.py | 2 +- tests/eko/evolution_operator/test_init.py | 53 +- .../eko/evolution_operator/test_init.py.patch | 601 --- .../test_matching_condition.py | 91 +- tests/eko/evolution_operator/test_ome.py | 20 +- tests/eko/evolution_operator/test_physical.py | 36 +- tests/eko/io/test_bases.py | 83 - tests/eko/io/test_manipulate.py | 274 +- tests/eko/io/test_metadata.py | 6 +- tests/eko/io/test_runcards.py | 90 - tests/eko/kernels/test_init.py | 21 + tests/eko/kernels/test_kernels_QEDns.py | 7 +- tests/eko/kernels/test_kernels_QEDsinglet.py | 12 +- tests/eko/kernels/test_kernels_QEDvalence.py | 16 +- tests/eko/kernels/test_ns.py | 37 +- tests/eko/kernels/test_s.py | 44 +- tests/eko/kernels/test_utils.py | 12 - tests/eko/quantities/test_couplings.py | 4 +- tests/eko/runner/__init__.py | 10 +- tests/eko/runner/conftest.py | 3 +- tests/eko/runner/test_legacy.py | 2 +- tests/eko/runner/test_operators.py | 6 +- tests/eko/scale_variations/test_diff.py | 182 + tests/eko/scale_variations/test_expanded.py | 206 +- tests/eko/test_beta.py | 1 + tests/eko/test_couplings.py | 39 +- tests/eko/test_gamma.py | 1 + tests/eko/test_matchings.py | 1 + tests/eko/test_msbar_masses.py | 4 +- tests/eko/test_quantities.py | 3 - tests/ekobox/test_apply.py | 11 +- tests/ekobox/test_cards.py | 8 +- tests/ekobox/test_evol_pdf.py | 18 +- tests/ekobox/test_info_file.py | 26 +- tests/ekobox/test_utils.py | 7 +- tests/ekomark/data/__init__.py | 0 tests/ekomark/data/test_init.py | 96 + .../polarized/space_like/test_ad_as2.py | 8 +- .../unpolarized/space_like/test_as4.py | 4 +- .../unpolarized/space_like/test_as4_fhmv.py | 4 +- .../polarized/space_like/test_nnlo.py | 20 +- .../unpolarized/space_like/test_as3.py | 29 +- 256 files changed, 6317 insertions(+), 5568 deletions(-) create mode 100644 .github/workflows/crates.yml create mode 100644 .github/workflows/maturin.yml create mode 100644 .github/workflows/unittests-rust.yml rename crates/Cargo.lock => Cargo.lock (75%) create mode 100644 Cargo.toml rename benchmarks/ekore/{benchmark_ad.py => benchmark_pegasus_ad_us_as2.py} (87%) create mode 100644 benchmarks/ekore/benchmark_pegasus_mellin.py create mode 100644 benchmarks/ekore/benchmark_pegasus_ome_ps_as2.py delete mode 100644 crates/Cargo.toml create mode 100644 crates/README.md create mode 100644 crates/bump-versions.py create mode 100644 crates/doc-header.html create mode 120000 crates/eko/doc-header.html create mode 120000 crates/eko/src/bib.rs create mode 120000 crates/ekore/doc-header.html create mode 100644 crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as2.rs create mode 100644 crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as3.rs create mode 100644 crates/ekore/src/harmonics/g_functions.rs create mode 100644 crates/ekore/src/harmonics/w2.rs create mode 100644 crates/ekore/src/harmonics/w3.rs create mode 100644 crates/ekore/src/harmonics/w4.rs create mode 100644 crates/parse-abbrev.py create mode 100644 crates/release.json create mode 100644 extras/lh_bench_23/parse_to_latex.py delete mode 100644 extras/lh_bench_23/plot_bench.py create mode 100644 extras/lh_bench_23/plot_trn_exa.py create mode 100644 extras/lh_bench_23/run-trn_exa.py rename extras/lh_bench_23/{run_fhmv.sh => run_fhmruvv.sh} (76%) create mode 100644 extras/lh_bench_23/tables/EKO.zip create mode 100644 extras/lh_bench_23/tables/MSHT.zip create mode 100644 extras/lh_bench_23/tables/table14-part1.csv create mode 100644 extras/lh_bench_23/tables/table15-part1.csv create mode 100644 extras/lh_bench_23/tables/table_FFNS-1_iterate-exact.csv create mode 100644 extras/lh_bench_23/tables/table_FFNS-1_truncated.csv create mode 100644 extras/lh_bench_23/tables/table_FFNS-2_iterate-exact.csv create mode 100644 extras/lh_bench_23/tables/table_FFNS-2_truncated.csv create mode 100644 extras/lh_bench_23/tables/table_FFNS-3_iterate-exact.csv create mode 100644 extras/lh_bench_23/tables/table_FFNS-3_truncated.csv delete mode 100644 src/eko/io/bases.py delete mode 100644 src/eko/kernels/utils.py delete mode 100644 tests/eko/evolution_operator/test_init.py.patch delete mode 100644 tests/eko/io/test_bases.py create mode 100644 tests/eko/kernels/test_init.py delete mode 100644 tests/eko/kernels/test_utils.py create mode 100644 tests/eko/scale_variations/test_diff.py create mode 100644 tests/ekomark/data/__init__.py create mode 100644 tests/ekomark/data/test_init.py diff --git a/.github/workflows/crates.yml b/.github/workflows/crates.yml new file mode 100644 index 000000000..935ce2aba --- /dev/null +++ b/.github/workflows/crates.yml @@ -0,0 +1,28 @@ +name: Deploy Crates + +on: + push: + tags: + - "*" + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - name: Install and configure Poetry + uses: snok/install-poetry@v1 + - name: Install task runner + run: pip install poethepoet + - name: Bump versions + run: | + poetry install --only version + poe bump-version + - name: Publish crates + run: | + jq '.[]' crates/release.json | xargs -I _ cargo publish -p _ --allow-dirty + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/maturin.yml b/.github/workflows/maturin.yml new file mode 100644 index 000000000..4680d0316 --- /dev/null +++ b/.github/workflows/maturin.yml @@ -0,0 +1,123 @@ +name: Deploy Maturin wheels + +on: + push: + tags: + - "*" + workflow_dispatch: + +permissions: + contents: read + +jobs: + linux: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-latest + target: x86_64 + - runner: ubuntu-latest + target: x86 + - runner: ubuntu-latest + target: aarch64 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter -m crates/eko/Cargo.toml + sccache: "true" + manylinux: auto + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + name: wheels-linux-${{ matrix.platform.target }} + path: dist + + windows: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: windows-latest + target: x64 + - runner: windows-latest + target: x86 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: ${{ matrix.platform.target }} + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter -m crates/eko/Cargo.toml + sccache: "true" + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + name: wheels-windows-${{ matrix.platform.target }} + path: dist + + macos: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: macos-latest + target: x86_64 + - runner: macos-14 + target: aarch64 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter -m crates/eko/Cargo.toml + sccache: "true" + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + name: wheels-macos-${{ matrix.platform.target }} + path: dist + + sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Build sdist + uses: PyO3/maturin-action@v1 + with: + command: sdist + args: --out dist -m crates/eko/Cargo.toml + - name: Upload sdist + uses: actions/upload-artifact@v4 + with: + name: wheels-sdist + path: dist + + release: + name: Release + runs-on: ubuntu-latest + if: "startsWith(github.ref, 'refs/tags/')" + needs: [linux, windows, macos, sdist] + steps: + - uses: actions/download-artifact@v4 + - name: Publish to PyPI + uses: PyO3/maturin-action@v1 + env: + MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + with: + command: upload + args: --non-interactive --skip-existing wheels-*/* diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 46040a1ae..45f89248b 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -7,7 +7,7 @@ on: jobs: publish: - uses: N3PDF/workflows/.github/workflows/python-poetry-pypi.yml@v2 + uses: NNPDF/workflows/.github/workflows/python-poetry-pypi.yml@v2 secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} with: diff --git a/.github/workflows/unittests-rust.yml b/.github/workflows/unittests-rust.yml new file mode 100644 index 000000000..2b05cb4d6 --- /dev/null +++ b/.github/workflows/unittests-rust.yml @@ -0,0 +1,21 @@ +name: Rust unit tests + +on: push + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - name: Install task runner + run: pip install poethepoet + - name: Run fmt + run: | + poe fmtcheck + - name: Run clippy + run: | + poe clippy + - name: Run Rust unit tests + run: | + poe rtest diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index ef3f7fa3f..a21b8531e 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -1,4 +1,4 @@ -name: tests +name: Python unit tests on: push @@ -6,10 +6,10 @@ jobs: test: strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11", "3.12"] fail-fast: false - uses: N3PDF/workflows/.github/workflows/python-poetry-tests.yml@v2 + uses: NNPDF/workflows/.github/workflows/python-poetry-tests.yml@v2 with: python-version: ${{ matrix.python-version }} poetry-extras: "-E mark -E box" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bee3e7adc..dfd0862f5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,10 +2,10 @@ # See https://pre-commit.com/hooks.html for more hooks ci: autofix_prs: false - skip: [fmt-eko, fmt-ekore] + skip: [fmt] # will be run by a separate CI repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -19,11 +19,11 @@ repos: - id: pycln args: [--config=pyproject.toml] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.12.1 + rev: 24.4.2 hooks: - id: black - repo: https://github.com/asottile/blacken-docs - rev: 1.16.0 + rev: 1.18.0 hooks: - id: blacken-docs - repo: https://github.com/pycqa/isort @@ -32,7 +32,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.17.0 hooks: - id: pyupgrade - repo: https://github.com/pycqa/pydocstyle @@ -43,25 +43,23 @@ repos: args: ["--add-ignore=D107,D105"] additional_dependencies: - toml - - repo: local + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.4.1 hooks: - - id: fmt-eko - name: fmt-eko - description: Format eko files with cargo fmt. - entry: cargo fmt --manifest-path crates/eko/Cargo.toml -- - language: system - files: ^crates/eko/.*\.rs$ - args: [] + - id: mypy + additional_dependencies: [types-PyYAML] + pass_filenames: false + args: ["--ignore-missing-imports", "src/"] - repo: local hooks: - - id: fmt-ekore - name: fmt-ekore - description: Format ekore files with cargo fmt. - entry: cargo fmt --manifest-path crates/ekore/Cargo.toml -- + - id: fmt + name: fmt + description: Format Rust files with cargo fmt. + entry: cargo fmt -- language: system - files: ^crates/ekore/.*\.rs$ + files: ^crates/.*\.rs$ args: [] - repo: https://github.com/pre-commit/pre-commit - rev: v3.6.0 + rev: v3.8.0 hooks: - id: validate_manifest diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 7b5c39c8d..e734d32c8 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,3 +1,7 @@ +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +# for poetry see https://docs.readthedocs.io/en/stable/build-customization.html#install-dependencies-with-poetry + +# Required version: 2 build: @@ -9,17 +13,13 @@ build: jobs: post_create_environment: - pip install poetry - - poetry config virtualenvs.create false post_install: - - poetry install --with docs + - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with docs +# Build documentation in the docs/ directory with Sphinx sphinx: configuration: doc/source/conf.py -# Optionally build your docs in additional formats such as PDF -# formats: -# - pdf - python: install: - method: pip diff --git a/crates/Cargo.lock b/Cargo.lock similarity index 75% rename from crates/Cargo.lock rename to Cargo.lock index b6d5d084d..80fa02400 100644 --- a/crates/Cargo.lock +++ b/Cargo.lock @@ -33,20 +33,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "eko" -version = "0.1.0" +version = "0.0.1" dependencies = [ "ekore", - "katexit", "num", ] [[package]] name = "ekore" -version = "0.1.0" +version = "0.0.1" dependencies = [ "float-cmp", "hashbrown", - "katexit", "num", ] @@ -69,17 +67,6 @@ dependencies = [ "allocator-api2", ] -[[package]] -name = "katexit" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1304c448ce2c207c2298a34bc476ce7ae47f63c23fa2b498583b26be9bc88c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "num" version = "0.4.1" @@ -162,41 +149,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" - [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..f26518890 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,22 @@ +[workspace] +members = ["crates/*"] +resolver = "2" + +[workspace.package] +authors = [ + "A. Barontini ", + "A. Candido ", + "F. Hekhorn ", + "N. Laurenti ", + "G. Magni ", + "T. Sharma ", +] +description = "Evolution Kernel Operators" +readme = "README.md" +categories = ["science"] +edition = "2021" +keywords = ["physics"] +license = "GPL-3.0-or-later" +repository = "https://github.com/NNPDF/eko" +rust-version = "1.60.0" +version = "0.0.1" diff --git a/README.md b/README.md index 8344d4cb1..aef72ca2f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@

Tests + Rust tests Docs CodeFactor diff --git a/benchmarks/DSSV_bench.py b/benchmarks/DSSV_bench.py index 3df7af356..4654f67d7 100644 --- a/benchmarks/DSSV_bench.py +++ b/benchmarks/DSSV_bench.py @@ -3,6 +3,7 @@ Note that the PDF set is private, but can be obtained from the authors upon request. """ + from banana import register from eko import interpolation diff --git a/benchmarks/NNPDF_bench.py b/benchmarks/NNPDF_bench.py index 0e939f9ea..444b452cd 100644 --- a/benchmarks/NNPDF_bench.py +++ b/benchmarks/NNPDF_bench.py @@ -1,6 +1,7 @@ """ Benchmark NNPDF pdf family """ + from banana import register from eko import interpolation diff --git a/benchmarks/apfel_bench.py b/benchmarks/apfel_bench.py index ae3189119..d40c65894 100644 --- a/benchmarks/apfel_bench.py +++ b/benchmarks/apfel_bench.py @@ -1,6 +1,7 @@ """ Benchmark EKO to Apfel """ + import numpy as np from banana import register from banana.data import cartesian_product @@ -20,7 +21,6 @@ def tolist(input_dict): class ApfelBenchmark(Runner): - """ Globally set the external program to Apfel """ diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 628c6b460..eea67e10c 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -35,7 +35,7 @@ // The Pythons you'd like to test against. If not provided, defaults // to the current version of Python used to run `asv`. - "pythons": ["3.8", "3.9", "3.10"], + "pythons": ["3.9", "3.10"], // The matrix of dependencies to test. Each key is the name of a // package (in PyPI) and the values are version numbers. An empty diff --git a/benchmarks/eko/benchmark_alphaem.py b/benchmarks/eko/benchmark_alphaem.py index 16e56ac4a..9cc05536c 100644 --- a/benchmarks/eko/benchmark_alphaem.py +++ b/benchmarks/eko/benchmark_alphaem.py @@ -35,9 +35,7 @@ def test_alphaQED_high(self): dict( alphas=0.118, alphaem=7.7553e-03, - scale=91.2, - num_flavs_ref=5, - max_num_flavs=5, + ref=(91.2, 5), em_running=True, ) ) @@ -75,9 +73,7 @@ def test_alphaQED_low(self): dict( alphas=0.118, alphaem=7.7553e-03, - scale=91.2, - num_flavs_ref=5, - max_num_flavs=5, + ref=(91.2, 5), em_running=True, ) ) @@ -124,9 +120,7 @@ def test_validphys(self): dict( alphas=0.118, alphaem=7.7553e-03, - scale=91.2, - num_flavs_ref=5, - max_num_flavs=5, + ref=(91.2, 5), em_running=True, ) ) diff --git a/benchmarks/eko/benchmark_evol_to_unity.py b/benchmarks/eko/benchmark_evol_to_unity.py index 41bc4b4d0..c466d00d8 100644 --- a/benchmarks/eko/benchmark_evol_to_unity.py +++ b/benchmarks/eko/benchmark_evol_to_unity.py @@ -19,16 +19,12 @@ def update_cards(theory: TheoryCard, operator: OperatorCard): theory.couplings = CouplingsInfo( alphas=0.35, alphaem=0.007496, - scale=float(np.sqrt(2)), - max_num_flavs=6, - num_flavs_ref=None, + ref=(float(np.sqrt(2)), 4), ) - theory.heavy.num_flavs_init = 4 - theory.heavy.intrinsic_flavors = [4, 5] theory.heavy.masses.c.value = 1.0 theory.heavy.masses.b.value = 4.75 theory.heavy.masses.t.value = 173.0 - operator.mu0 = float(np.sqrt(2)) + operator.init = (float(np.sqrt(2)), 4) operator.mugrid = [(10, 5)] operator.xgrid = XGrid(np.linspace(1e-1, 1, 30)) operator.configs.interpolation_polynomial_degree = 1 diff --git a/benchmarks/eko/benchmark_inverse_matching.py b/benchmarks/eko/benchmark_inverse_matching.py index d9c16b0b2..d63b776f0 100644 --- a/benchmarks/eko/benchmark_inverse_matching.py +++ b/benchmarks/eko/benchmark_inverse_matching.py @@ -20,14 +20,9 @@ couplings=dict( alphas=0.118, alphaem=0.007496252, - scale=91.2, - num_flavs_ref=5, - max_num_flavs=6, + ref=(91.2, 5), ), heavy=dict( - num_flavs_init=4, - num_flavs_max_pdf=6, - intrinsic_flavors=[], masses=[ReferenceRunning([mq, np.nan]) for mq in (MC, 4.92, 172.5)], masses_scheme="POLE", matching_ratios=[1.0, 1.0, np.inf], @@ -40,7 +35,7 @@ # operator settings op_raw = dict( - mu0=1.65, + init=(1.65, 4), xgrid=[0.0001, 0.001, 0.01, 0.1, 1], mugrid=[(MC, 3), (MC, 4)], configs=dict( diff --git a/benchmarks/eko/benchmark_msbar_evolution.py b/benchmarks/eko/benchmark_msbar_evolution.py index 6286e15ad..49dc0e952 100644 --- a/benchmarks/eko/benchmark_msbar_evolution.py +++ b/benchmarks/eko/benchmark_msbar_evolution.py @@ -1,4 +1,5 @@ """This module benchmarks MSbar mass evolution against APFEL.""" + import numpy as np import pytest @@ -20,9 +21,8 @@ def update_theory(theory: TheoryCard): theory.order = (3, 0) - theory.couplings.scale = 91 + theory.couplings.ref = (91, 5) theory.couplings.alphaem = 0.007496 - theory.couplings.num_flavs_ref = 5 theory.heavy.masses_scheme = QuarkMassScheme.MSBAR theory.heavy.masses.c = QuarkMassRef([1.5, 18]) theory.heavy.masses.b = QuarkMassRef([4.1, 20]) @@ -149,7 +149,7 @@ def benchmark_APFEL_msbar_evolution( apfel.SetTheory("QCD") apfel.SetPerturbativeOrder(order - 1) apfel.SetAlphaEvolution(method) - apfel.SetAlphaQCDRef(coupl.alphas, coupl.scale) + apfel.SetAlphaQCDRef(coupl.alphas, coupl.ref[0]) apfel.SetVFNS() apfel.SetMSbarMasses( qmasses.c.value, qmasses.b.value, qmasses.t.value @@ -217,7 +217,7 @@ def benchmark_APFEL_msbar_solution( apfel.SetTheory("QCD") apfel.SetPerturbativeOrder(order - 1) apfel.SetAlphaEvolution("exact") - apfel.SetAlphaQCDRef(coupl.alphas, coupl.scale) + apfel.SetAlphaQCDRef(coupl.alphas, coupl.ref[0]) apfel.SetVFNS() apfel.SetMSbarMasses(qmasses.c.value, qmasses.b.value, qmasses.t.value) apfel.SetMassScaleReference( diff --git a/benchmarks/eko/benchmark_strong_coupling.py b/benchmarks/eko/benchmark_strong_coupling.py index d13a264bd..d60bd28b0 100644 --- a/benchmarks/eko/benchmark_strong_coupling.py +++ b/benchmarks/eko/benchmark_strong_coupling.py @@ -8,7 +8,7 @@ from eko.couplings import Couplings from eko.io.runcards import TheoryCard from eko.quantities.couplings import CouplingEvolutionMethod, CouplingsInfo -from eko.quantities.heavy_quarks import QuarkMassScheme +from eko.quantities.heavy_quarks import FlavorsNumber, QuarkMassScheme # try to load LHAPDF - if not available, we'll use the cached values try: @@ -35,16 +35,11 @@ use_PEGASUS = False -def ref_couplings( - ref_values, - ref_scale: float, -) -> CouplingsInfo: +def ref_couplings(ref_values, ref_scale: float, ref_nf: FlavorsNumber) -> CouplingsInfo: return CouplingsInfo( alphas=ref_values[0], alphaem=ref_values[1], - scale=ref_scale, - max_num_flavs=6, - num_flavs_ref=None, + ref=(ref_scale, ref_nf), ) @@ -54,11 +49,11 @@ def test_a_s(self): """Tests the value of alpha_s (for now only at LO) for a given set of parameters """ - # TODO @JCM: we need a source for this! + # source: JCM known_val = 0.0091807954 ref_mu2 = 90 ask_q2 = 125 - ref = ref_couplings([0.1181, 0.007496], np.sqrt(ref_mu2)) + ref = ref_couplings([0.1181, 0.007496], np.sqrt(ref_mu2), 5) as_FFNS_LO = Couplings( couplings=ref, order=(1, 0), @@ -80,7 +75,7 @@ def benchmark_LHA_paper(self): # LO - FFNS # note that the LO-FFNS value reported in :cite:`Giele:2002hx` # was corrected in :cite:`Dittmar:2005ed` - coupling_ref = ref_couplings([0.35, 0.007496], np.sqrt(2)) + coupling_ref = ref_couplings([0.35, 0.007496], np.sqrt(2), 4) as_FFNS_LO = Couplings( couplings=coupling_ref, order=(1, 0), @@ -141,7 +136,7 @@ def benchmark_APFEL_ffns(self): threshold_holder = matchings.Atlas.ffns(nf, 0.0) for order in [1, 2, 3]: as_FFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=threshold_holder.walls[1:-1], @@ -212,8 +207,7 @@ def benchmark_pegasus_ffns(self): } # collect my values threshold_holder = matchings.Atlas.ffns(nf, 0.0) - couplings = ref_couplings(coupling_ref, scale_ref) - couplings.max_num_flavs = 4 + couplings = ref_couplings(coupling_ref, scale_ref, nf) for order in [1, 2, 3, 4]: as_FFNS = Couplings( couplings=couplings, @@ -259,6 +253,7 @@ def benchmark_APFEL_vfns(self): Q2s = [1, 2**2, 3**2, 90**2, 100**2] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_ref = 5 threshold_list = np.power([2, 4, 175], 2) apfel_vals_dict = { 1: np.array( @@ -292,7 +287,7 @@ def benchmark_APFEL_vfns(self): # collect my values for order in [1, 2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=threshold_list, @@ -339,8 +334,9 @@ def benchmark_APFEL_vfns_fact_to_ren(self): ] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_refs = (5, 6) fact_to_ren_lin_list = [0.567, 2.34] - threshold_list = np.power([2, 2 * 4, 2 * 92], 2) + masses_list = np.power([2, 2 * 4, 2 * 92], 2) apfel_vals_dict_list = [ { 1: np.array( @@ -431,16 +427,16 @@ def benchmark_APFEL_vfns_fact_to_ren(self): ), }, ] - for fact_to_ren_lin, apfel_vals_dict in zip( - fact_to_ren_lin_list, apfel_vals_dict_list + for fact_to_ren_lin, apfel_vals_dict, nf_ref in zip( + fact_to_ren_lin_list, apfel_vals_dict_list, nf_refs ): # collect my values for order in [1, 2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXACT, - masses=threshold_list.tolist(), + masses=masses_list.tolist(), hqm_scheme=QuarkMassScheme.POLE, thresholds_ratios=np.array([1.0, 1.0, 1.0]) / fact_to_ren_lin**2, ) @@ -457,7 +453,7 @@ def benchmark_APFEL_vfns_fact_to_ren(self): apfel.SetAlphaEvolution("exact") apfel.SetAlphaQCDRef(coupling_ref[0], scale_ref) apfel.SetVFNS() - apfel.SetPoleMasses(*np.sqrt(threshold_list)) + apfel.SetPoleMasses(*np.sqrt(masses_list)) apfel.SetRenFacRatio(1.0 / fact_to_ren_lin) apfel.InitializeAPFEL() # collect a_s @@ -468,12 +464,18 @@ def benchmark_APFEL_vfns_fact_to_ren(self): ) np.testing.assert_allclose(apfel_vals, np.array(apfel_vals_cur)) # check myself to APFEL - np.testing.assert_allclose(apfel_vals, np.array(my_vals), rtol=2.5e-5) + np.testing.assert_allclose( + apfel_vals, + np.array(my_vals), + rtol=2.5e-5, + err_msg=f"{order=},{fact_to_ren_lin=}", + ) def benchmark_APFEL_vfns_threshold(self): Q2s = np.power([30, 96, 150], 2) coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_ref = 4 threshold_list = np.power([30, 95, 240], 2) thresholds_ratios = [2.34**2, 1.0**2, 0.5**2] apfel_vals_dict = { @@ -487,7 +489,7 @@ def benchmark_APFEL_vfns_threshold(self): # collect my values for order in [2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=threshold_list.tolist(), @@ -496,7 +498,6 @@ def benchmark_APFEL_vfns_threshold(self): ) my_vals = [] for Q2 in Q2s: - print(Q2) my_vals.append(as_VFNS.a(Q2)[0]) # get APFEL numbers - if available else use cache apfel_vals = apfel_vals_dict[order] @@ -516,7 +517,6 @@ def benchmark_APFEL_vfns_threshold(self): apfel_vals_cur = [] for Q2 in Q2s: apfel_vals_cur.append(apfel.AlphaQCD(np.sqrt(Q2)) / (4.0 * np.pi)) - print(apfel_vals_cur) np.testing.assert_allclose(apfel_vals, np.array(apfel_vals_cur)) # check myself to APFEL np.testing.assert_allclose(apfel_vals, np.array(my_vals)) @@ -525,6 +525,7 @@ def benchmark_APFEL_vfns_msbar(self): Q2s = np.power([3, 96, 150], 2) coupling_ref = np.array([0.118, 0.007496]) scale_ref = 91.0 + nf_ref = 5 Q2m = np.power([2.0, 4.0, 175], 2) m2s = np.power((1.4, 4.0, 175), 2) apfel_vals_dict = { @@ -538,7 +539,7 @@ def benchmark_APFEL_vfns_msbar(self): # collect my values for order in [2, 3]: as_VFNS = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf_ref), order=(order, 0), method=CouplingEvolutionMethod.EXPANDED, masses=m2s.tolist(), @@ -586,7 +587,7 @@ def benchmark_lhapdf_ffns_lo(self): # collect my values threshold_holder = matchings.Atlas.ffns(nf, 0.0) as_FFNS_LO = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(1, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_holder.walls[1:-1], @@ -629,8 +630,9 @@ def benchmark_apfel_exact(self): Q2s = [1e1, 1e2, 1e3, 1e4] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 90 + nf = 3 # collect my values - threshold_holder = matchings.Atlas.ffns(3, 0.0) + threshold_holder = matchings.Atlas.ffns(nf, 0.0) # LHAPDF cache apfel_vals_dict = { 1: np.array( @@ -660,7 +662,7 @@ def benchmark_apfel_exact(self): } for order in range(1, 3 + 1): sc = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(order, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_holder.walls[1:-1], @@ -696,8 +698,9 @@ def benchmark_lhapdf_exact(self): Q2s = [1e1, 1e2, 1e3, 1e4] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 90 + nf = 3 # collect my values - threshold_holder = matchings.Atlas.ffns(3, 0.0) + threshold_holder = matchings.Atlas.ffns(nf, 0.0) # LHAPDF cache lhapdf_vals_dict = { 1: np.array( @@ -735,7 +738,7 @@ def benchmark_lhapdf_exact(self): } for order in range(1, 4 + 1): sc = Couplings( - couplings=ref_couplings(coupling_ref, scale_ref), + couplings=ref_couplings(coupling_ref, scale_ref, nf), order=(order, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_holder.walls[1:-1], @@ -766,6 +769,7 @@ def benchmark_lhapdf_zmvfns_lo(self): Q2s = [1, 1e1, 1e2, 1e3, 1e4] coupling_ref = np.array([0.118, 0.007496]) scale_ref = 900 + nf_ref = 5 m2c = 2.0 m2b = 25.0 m2t = 1500.0 @@ -785,7 +789,7 @@ def benchmark_lhapdf_zmvfns_lo(self): # collect my values as_VFNS_LO = Couplings( - couplings=ref_couplings(coupling_ref, np.sqrt(scale_ref)), + couplings=ref_couplings(coupling_ref, np.sqrt(scale_ref), nf_ref), order=(1, 0), method=CouplingEvolutionMethod.EXACT, masses=threshold_list, @@ -836,10 +840,8 @@ def benchmark_APFEL_fact_to_ren_lha_settings(self, theory_card: TheoryCard): theory = theory_card theory.order = (3, 0) theory.couplings.alphas = 0.35 - theory.couplings.scale = float(np.sqrt(2)) theory.couplings.alphaem = 0.007496 - theory.couplings.num_flavs_ref = 4 - theory.heavy.num_flavs_init = 3 + theory.couplings.ref = (float(np.sqrt(2)), 4) theory.xif = np.sqrt(1.0 / 2.0) theory.heavy.masses.c.value = np.sqrt(2.0) theory.heavy.masses.b.value = 4.5 @@ -881,7 +883,7 @@ def benchmark_APFEL_fact_to_ren_lha_settings(self, theory_card: TheoryCard): apfel.SetTheory("QCD") apfel.SetPerturbativeOrder(theory.order[0] - 1) apfel.SetAlphaEvolution("exact") - apfel.SetAlphaQCDRef(theory.couplings.alphas, theory.couplings.scale) + apfel.SetAlphaQCDRef(theory.couplings.alphas, theory.couplings.ref[0]) apfel.SetVFNS() apfel.SetPoleMasses(qmasses.c.value, qmasses.b.value, qmasses.t.value) apfel.SetMassMatchingScales( diff --git a/benchmarks/ekobox/benchmark_evol_pdf.py b/benchmarks/ekobox/benchmark_evol_pdf.py index 3a9dc0f4a..a0ddcaac4 100644 --- a/benchmarks/ekobox/benchmark_evol_pdf.py +++ b/benchmarks/ekobox/benchmark_evol_pdf.py @@ -21,15 +21,13 @@ def benchmark_evolve_single_member( theory = theory_card theory.order = (1, 0) theory.couplings.alphas = 0.118000 - theory.couplings.scale = 91.1876 + theory.couplings.ref = (91.1876, 5) theory.couplings.alphaem = 0.007496 - theory.couplings.max_num_flavs = 3 - theory.heavy.num_flavs_max_pdf = 3 theory.heavy.masses.c.value = 1.3 theory.heavy.masses.b.value = 4.75 theory.heavy.masses.t.value = 172 op = operator_card - op.mu0 = 5.0 + op.init = (5.0, 4) op.mugrid = mugrid # lhapdf import (maybe i have to dump with a x*), do plots) with lhapdf_path(test_pdf): @@ -49,7 +47,7 @@ def benchmark_evolve_single_member( ev_pdf = lhapdf.mkPDF("EvPDF", 0) assert info["XMin"] == op.xgrid.raw[0] assert info["SetDesc"] == "MyEvolvedPDF" - assert info["MZ"] == theory.couplings.scale + assert info["MZ"] == theory.couplings.ref[0] assert info["Debug"] == "Debug" xgrid = op.xgrid.raw for idx, mu2 in enumerate(op.mu2grid): @@ -76,7 +74,7 @@ def benchmark_evolve_more_members( theory = theory_card theory.order = (1, 0) op = operator_card - op.mu0 = 1.0 + op.init = (1.0, 3) op.mugrid = [(10.0, 5), (100.0, 5)] op.xgrid = XGrid([1e-7, 0.01, 0.1, 0.2, 0.3]) with lhapdf_path(test_pdf): diff --git a/benchmarks/ekore/benchmark_ad.py b/benchmarks/ekore/benchmark_pegasus_ad_us_as2.py similarity index 87% rename from benchmarks/ekore/benchmark_ad.py rename to benchmarks/ekore/benchmark_pegasus_ad_us_as2.py index c3c8de01e..ebc53e3ae 100644 --- a/benchmarks/ekore/benchmark_ad.py +++ b/benchmarks/ekore/benchmark_pegasus_ad_us_as2.py @@ -1,4 +1,8 @@ -"""Benchmark the NLO anomalous dimensions against PEGASUS""" +"""Benchmark the unpolarized NLO anomalous dimensions against PEGASUS. + +Recall that we obtained our representation not from PEGASUS, but derived it +ourselves (see comment there).""" + import numpy as np import pytest @@ -7,39 +11,6 @@ from eko.constants import CA, CF, TR, zeta2, zeta3 -@pytest.mark.isolated -def benchmark_melling_g3_pegasus(): - for N in [1, 2, 3, 4, 1 + 1j, 1 - 1j, 2 + 1j, 3 + 1j]: - check_melling_g3_pegasus(N) - - -def check_melling_g3_pegasus(N): - S1 = h.S1(N) - N1 = N + 1.0 - N2 = N + 2.0 - N3 = N + 3.0 - N4 = N + 4.0 - N5 = N + 5.0 - N6 = N + 6.0 - S11 = S1 + 1.0 / N1 - S12 = S11 + 1.0 / N2 - S13 = S12 + 1.0 / N3 - S14 = S13 + 1.0 / N4 - S15 = S14 + 1.0 / N5 - S16 = S15 + 1.0 / N6 - - SPMOM = ( - 1.0000 * (zeta2 - S1 / N) / N - - 0.9992 * (zeta2 - S11 / N1) / N1 - + 0.9851 * (zeta2 - S12 / N2) / N2 - - 0.9005 * (zeta2 - S13 / N3) / N3 - + 0.6621 * (zeta2 - S14 / N4) / N4 - - 0.3174 * (zeta2 - S15 / N5) / N5 - + 0.0699 * (zeta2 - S16 / N6) / N6 - ) - np.testing.assert_allclose(h.g_functions.mellin_g3(N, S1), SPMOM) - - @pytest.mark.isolated def benchmark_gamma_ns_1_pegasus(): # remember that singlet has pole at N=1 @@ -53,7 +24,6 @@ def check_gamma_1_pegasus(N, NF): ZETA2 = zeta2 ZETA3 = zeta3 - # N = np.random.rand(1) + np.random.rand(1) * 1j S1 = h.S1(N) S2 = h.S2(N) diff --git a/benchmarks/ekore/benchmark_pegasus_mellin.py b/benchmarks/ekore/benchmark_pegasus_mellin.py new file mode 100644 index 000000000..addefe421 --- /dev/null +++ b/benchmarks/ekore/benchmark_pegasus_mellin.py @@ -0,0 +1,41 @@ +"""Benchmark the Mellin transforms against PEGASUS.""" + +import numpy as np +import pytest + +import ekore.anomalous_dimensions.unpolarized.space_like.as2 as ad_as2 +import ekore.harmonics as h +from eko.constants import CA, CF, TR, zeta2, zeta3 + + +@pytest.mark.isolated +def benchmark_melling_g3_pegasus(): + for N in [1, 2, 3, 4, 1 + 1j, 1 - 1j, 2 + 1j, 3 + 1j]: + check_melling_g3_pegasus(N) + + +def check_melling_g3_pegasus(N): + S1 = h.S1(N) + N1 = N + 1.0 + N2 = N + 2.0 + N3 = N + 3.0 + N4 = N + 4.0 + N5 = N + 5.0 + N6 = N + 6.0 + S11 = S1 + 1.0 / N1 + S12 = S11 + 1.0 / N2 + S13 = S12 + 1.0 / N3 + S14 = S13 + 1.0 / N4 + S15 = S14 + 1.0 / N5 + S16 = S15 + 1.0 / N6 + + SPMOM = ( + 1.0000 * (zeta2 - S1 / N) / N + - 0.9992 * (zeta2 - S11 / N1) / N1 + + 0.9851 * (zeta2 - S12 / N2) / N2 + - 0.9005 * (zeta2 - S13 / N3) / N3 + + 0.6621 * (zeta2 - S14 / N4) / N4 + - 0.3174 * (zeta2 - S15 / N5) / N5 + + 0.0699 * (zeta2 - S16 / N6) / N6 + ) + np.testing.assert_allclose(h.g_functions.mellin_g3(N, S1), SPMOM) diff --git a/benchmarks/ekore/benchmark_pegasus_ome_ps_as2.py b/benchmarks/ekore/benchmark_pegasus_ome_ps_as2.py new file mode 100644 index 000000000..66b471c57 --- /dev/null +++ b/benchmarks/ekore/benchmark_pegasus_ome_ps_as2.py @@ -0,0 +1,199 @@ +"""Benchmark the polarized NNLO OME against PEGASUS""" + +import numpy as np +import pytest + +import ekore.harmonics as h +import ekore.operator_matrix_elements.polarized.space_like.as2 as ome_as2 +from eko.constants import CA, CF, TR, zeta2, zeta3 + + +@pytest.mark.isolated +def benchmark_pegasus_ome_ps_as2(): + # remember that singlet has pole at N=1 + for N in [2, 3, 4, +1j, -1j, +1j, +1j]: + for NF in [3, 4, 5]: + check_pegasus_ome_ps_as2_s(N, NF) + + +def check_pegasus_ome_ps_as2_s(N, NF): + # Test against pegasus implementation by Ignacio Borsa + ZETA2 = zeta2 + ZETA3 = zeta3 + + S1 = h.S1(N) + S2 = h.S2(N) + S3 = h.S3(N) + # + NM = N - 1.0 + N1 = N + 1.0 + N2 = N + 2.0 + NI = 1.0 / N + NMI = 1.0 / NM + N1I = 1.0 / N1 + N2I = 1.0 / N2 + # + S1M = S1 - NI + S2M = S2 - NI * NI + S3M = S3 - NI**3 + S11 = S1 + N1I + S21 = S2 + N1I * N1I + S31 = S3 + N1I**3 + S22 = S21 + N2I * N2I + ACG3 = h.g_functions.mellin_g3(N1, S11) + # + # CALL BET(N1,V1) + # CALL BET1(N1,V2) + # CALL BET2(N1,V3) + # CALL BET3(N1,V4) + V1 = ( + h.polygamma.cern_polygamma((N1 + 1.0) / 2.0, 0) + - h.polygamma.cern_polygamma(N1 / 2.0, 0) + ) / 2.0 + V2 = ( + h.polygamma.cern_polygamma((N1 + 1.0) / 2.0, 1) + - h.polygamma.cern_polygamma(N1 / 2.0, 1) + ) / 4.0 + V3 = ( + h.polygamma.cern_polygamma((N1 + 1.0) / 2.0, 2) + - h.polygamma.cern_polygamma(N1 / 2.0, 2) + ) / 8.0 + # + # + # ..The moments of the OME's DA_Hq^{PS,(2)} and DA_Hg^{S,(2)} given in + # Eqs. (138) and (111) of BBDKS. Note that for the former, an + # additional finite renormalization is needed to go from the Larin + # to the the M scheme + # + # + # ... Anomalous dimension terms + # + G0QG_HAT = -8 * TR * NM / N / N1 + # + G0GQ = -4 * CF * N2 / N / N1 + # + G0QQ = -CF * (2 * (2.0 + 3.0 * N + 3.0 * N**2) / N / N1 - 8.0 * S1) + # + # ... Polinomials in N + POL1 = ( + 12 * N**8 + 52 * N**7 + 60 * N**6 - 25 * N**4 - 2 * N**3 + 3 * N**2 + 8 * N + 4 + ) + # + POL2 = ( + 2.0 * N**8 + + 10.0 * N**7 + + 22.0 * N**6 + + 36.0 * N**5 + + 29.0 * N**4 + + 4.0 * N**3 + + 33.0 * N**2 + + 12.0 * N + + 4 + ) + # + POLR3 = 15 * N**6 + 45 * N**5 + 374 * N**4 + 601 * N**3 + 161 * N**2 - 24 * N + 36 + # + POLR8 = ( + -15 * N**8 + - 60 * N**7 + - 82 * N**6 + - 44 * N**5 + - 15 * N**4 + - 4 * N**2 + - 12 * N + - 8 + ) + # + # ... Finite renormalization term from Larin to M scheme + # + ZQQPS = -CF * TR * 8 * N2 * (N**2 - N - 1.0) / N**3 / N1**3 + # + A2HQ = ( + -4 + * CF + * TR + * N2 + / N**2 + / N1**2 + * (NM * (2 * S2 + ZETA2) - (4 * N**3 - 4 * N**2 - 3 * N - 1) / N**2 / N1**2) + + ZETA2 / 8 * G0QG_HAT * G0GQ + ) + # + # + A2HG = ( + CF + * TR + * ( + 4.0 + / 3 + * NM + / N + / N1 + * (-4.0 * S3 + S1**3 + 3.0 * S1 * S2 + 6.0 * S1 * ZETA2) + - 4 + * (N**4 + 17.0 * N**3 + 43.0 * N**2 + 33.0 * N + 2) + * S2 + / N**2 + / N1**2 + / N2 + - 4 * (3.0 * N**2 + 3.0 * N - 2) * S1**2 / N**2 / N1 / N2 + - 2 * NM * (3.0 * N**2 + 3.0 * N + 2) * ZETA2 / N**2 / N1**2 + - 4 * (N**3 - 2.0 * N**2 - 22.0 * N - 36) * S1 / N**2 / N1 / N2 + - 2 * POL1 / N**4 / N1**4 / N2 + ) + + CA + * TR + * ( + 4 * (N**2 + 4.0 * N + 5) * S1**2 / N / N1**2 / N2 + + 4 * (7.0 * N**3 + 24.0 * N**2 + 15.0 * N - 16) * S2 / N**2 / N1**2 / N2 + + 8 * NM * N2 * ZETA2 / N**2 / N1**2 + + 4 * (N**4 + 4.0 * N**3 - N**2 - 10.0 * N + 2) * S1 / N / N1**3 / N2 + - 4 * POL2 / N**4 / N1**4 / N2 + - 16 * NM / N / N1**2 * V2 + + 4 + * NM + / 3.0 + / N + / N1 + * ( + 12.0 * ACG3 + + 3.0 * V3 + - 8.0 * S3 + - S1**3 + - 9.0 * S1 * S2 + - 12.0 * S1 * V2 + - 12.0 * V1 * ZETA2 + - 3.0 * ZETA3 + ) + ) + # ... added simplified Gamma0_gg+2*beta0 + + 1 / 8 * G0QG_HAT * (8 * CA * (-2.0 / N / N1 + S1) - G0QQ) + ) + # + # ..The moments of the OME's DA_{gq,H}^{S,(2)} and DA_{gg,H}^{S,(2)} + # given in Eqs. (175) and (188) of Bierenblaum et al. + # + A2GQ = ( + CF + * TR + * N2 + * ( + 8 * (22.0 + 41.0 * N + 28.0 * N**2) / 27.0 / N / N1**3 + - 8 * (2.0 + 5.0 * N) * S1 / 9.0 / N / N1**2 + + 4 * (S1**2 + S2) / 3.0 / N / N1 + ) + ) + # + A2GG = ( + CA + * TR + * (2 * POLR3 / 27.0 / N**3 / N1**3 - 4 * (47.0 + 56.0 * N) * S1 / 27.0 / N1) + + CF * TR * POLR8 / N**4 / N1**4 + ) + + cache = h.cache.reset() + omeS2 = ome_as2.A_singlet(N, cache, 0.0, NF) + np.testing.assert_allclose(omeS2[0, 0], A2GG, err_msg=f"gg,{N=}") + np.testing.assert_allclose(omeS2[0, 1], A2GQ, err_msg=f"gq,{N=}") + np.testing.assert_allclose(omeS2[2, 1], A2HQ + NF * ZQQPS, err_msg=f"hq,{N=}") + np.testing.assert_allclose(omeS2[2, 0], A2HG, err_msg=f"hg,{N=}") diff --git a/benchmarks/lha_paper_bench.py b/benchmarks/lha_paper_bench.py index 9254307dc..bdc48ce59 100644 --- a/benchmarks/lha_paper_bench.py +++ b/benchmarks/lha_paper_bench.py @@ -1,6 +1,7 @@ """ Benchmark to :cite:`Giele:2002hx` (LO + NLO) and :cite:`Dittmar:2005ed` (NNLO). """ + import os import numpy as np @@ -12,19 +13,15 @@ register(__file__) +_sqrt2 = float(np.sqrt(2.0)) + base_theory = { "ModEv": "EXA", - "Q0": np.sqrt( - 2.0 - ), # Eq. (30) :cite:`Giele:2002hx`, Eq. (4.53) :cite:`Dittmar:2005ed` - "mc": np.sqrt( - 2.0 - ), # Eq. (34) :cite:`Giele:2002hx`, Eq. (4.56) :cite:`Dittmar:2005ed` + "Q0": _sqrt2, # Eq. (30) :cite:`Giele:2002hx`, Eq. (4.53) :cite:`Dittmar:2005ed` + "mc": _sqrt2, # Eq. (34) :cite:`Giele:2002hx`, Eq. (4.56) :cite:`Dittmar:2005ed` "mb": 4.5, "mt": 175, - "Qref": np.sqrt( - 2.0 - ), # Eq. (32) :cite:`Giele:2002hx`,Eq. (4.53) :cite:`Dittmar:2005ed` + "Qref": _sqrt2, # Eq. (32) :cite:`Giele:2002hx`,Eq. (4.53) :cite:`Dittmar:2005ed` "alphas": 0.35, # Eq. (4.55) :cite:`Dittmar:2005ed` "alphaqed": 0.007496, "QED": 0, @@ -78,11 +75,11 @@ def sv_theories(self, pto): """ low = self.theory.copy() low["PTO"] = pto - low["XIF"] = np.sqrt(1.0 / 2.0) + low["XIF"] = 1.0 / _sqrt2 low["ModSV"] = "exponentiated" high = self.theory.copy() high["PTO"] = pto - high["XIF"] = np.sqrt(2.0) + high["XIF"] = _sqrt2 high["ModSV"] = "exponentiated" return [high, low] @@ -301,7 +298,7 @@ def benchmark_sv(self, pto): sv_theory["kcThr"] = 1.0 + 1e-15 sv_theory["nfref"] = 4 sv_theory["EScaleVar"] = 0 - low["XIR"] = np.sqrt(2.0) - high["XIR"] = np.sqrt(0.5) + low["XIR"] = _sqrt2 + high["XIR"] = 1.0 / _sqrt2 self.run_lha([low, high]) diff --git a/crates/Cargo.toml b/crates/Cargo.toml deleted file mode 100644 index 8a69f7202..000000000 --- a/crates/Cargo.toml +++ /dev/null @@ -1,3 +0,0 @@ -[workspace] - -members = ["eko", "ekore"] diff --git a/crates/README.md b/crates/README.md new file mode 100644 index 000000000..baa27a087 --- /dev/null +++ b/crates/README.md @@ -0,0 +1,18 @@ +# Welcome to the rusty side of EKO! + +Here, we develop the Rust components of the EKO library + +## Crates + +- `ekore` contains the underlying collinear anomalous dimensions and the operator matrix elements +- `eko` is the glue between the Python side and the `ekore` crate + +## Files + +- `release.json` defines the releasing order of crates + - only listed crates will be released + - dependent crates should follow those they are depending on +- `katex-header.html` is an HTML snippet to be included in every docs page to inject + KaTeX support +- `bump-versions.py` increases the Rust versions in all crates consistently +- `make_bib.py` generates the Rust function stubs which serve as fake bibliography system diff --git a/crates/bump-versions.py b/crates/bump-versions.py new file mode 100644 index 000000000..6b7220f7e --- /dev/null +++ b/crates/bump-versions.py @@ -0,0 +1,40 @@ +import json +import sys +from pathlib import Path + +import tomlkit + +HERE = Path(__file__).parent +CRATES = json.loads((HERE / "release.json").read_text()) + + +def workspace(manifest, version): + manifest["workspace"]["package"]["version"] = version + return manifest + + +def crate(manifest, version): + internals = set(manifest["dependencies"].keys()).intersection(CRATES) + for dep in internals: + manifest["dependencies"][dep]["version"] = version + return manifest + + +def update(path, version, edit): + path = HERE / Path(path) / "Cargo.toml" + manifest = tomlkit.parse(path.read_text()) + manifest = edit(manifest, version) + path.write_text(tomlkit.dumps(manifest)) + + +def main(version): + update("..", version, workspace) + for name in CRATES: + update(name, version, crate) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + raise ValueError(f"Pass a version (e.g. v0.0.0) to {sys.argv[0]}") + # `git describe` starts with a `v` which we need to remove again + main(sys.argv[1][1:]) diff --git a/crates/doc-header.html b/crates/doc-header.html new file mode 100644 index 000000000..3b2f9651b --- /dev/null +++ b/crates/doc-header.html @@ -0,0 +1,65 @@ + + + + diff --git a/crates/eko/Cargo.toml b/crates/eko/Cargo.toml index 50aee6504..0fffdea1a 100644 --- a/crates/eko/Cargo.toml +++ b/crates/eko/Cargo.toml @@ -1,7 +1,19 @@ [package] name = "eko" -version = "0.1.0" -edition = "2021" + +authors.workspace = true +description.workspace = true +readme.workspace = true +categories.workspace = true +edition.workspace = true +keywords.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +[package.metadata.docs.rs] +rustdoc-args = ["--html-in-header", "doc-header.html"] [lib] name = "ekors" @@ -9,5 +21,4 @@ crate-type = ["cdylib"] [dependencies] num = "0.4.1" -katexit = "0.1.4" -ekore = { version = "0.1.0", path = "../ekore" } +ekore = { path = "../ekore", version = "0.0.1" } diff --git a/crates/eko/doc-header.html b/crates/eko/doc-header.html new file mode 120000 index 000000000..22282661d --- /dev/null +++ b/crates/eko/doc-header.html @@ -0,0 +1 @@ +../doc-header.html \ No newline at end of file diff --git a/crates/eko/pyproject.toml b/crates/eko/pyproject.toml index 2fff64504..7b2921e04 100644 --- a/crates/eko/pyproject.toml +++ b/crates/eko/pyproject.toml @@ -3,8 +3,8 @@ requires = ["maturin>=1.1,<2.0"] build-backend = "maturin" [project] -name = "ekors" -requires-python = ">=3.8" +name = "eko-rs" +requires-python = ">=3.9" classifiers = [ "Programming Language :: Rust", "Programming Language :: Python :: Implementation :: CPython", diff --git a/crates/eko/src/bib.rs b/crates/eko/src/bib.rs new file mode 120000 index 000000000..1e713280e --- /dev/null +++ b/crates/eko/src/bib.rs @@ -0,0 +1 @@ +../../ekore/src/bib.rs \ No newline at end of file diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index e6b3e44cc..67bf8956a 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -1,12 +1,15 @@ //! Interface to the eko Python package. -use ekore; use ekore::harmonics::cache::Cache; use std::ffi::c_void; -mod mellin; +pub mod bib; +pub mod mellin; /// QCD intergration kernel inside quad. +/// +/// # Safety +/// This is the connection from Python, so we don't know what is on the other side. #[no_mangle] pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { let args = *(rargs as *mut QuadQCDargs); @@ -23,11 +26,11 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { &mut c, args.nf, ); - for k in 0..args.order_qcd { - for l in 0..2 { - for m in 0..2 { - re.push(res[k][l][m].re); - im.push(res[k][l][m].im); + for gamma_s in res.iter().take(args.order_qcd) { + for col in gamma_s.iter().take(2) { + for el in col.iter().take(2) { + re.push(el.re); + im.push(el.im); } } } @@ -38,9 +41,9 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { &mut c, args.nf, ); - for j in 0..args.order_qcd { - re.push(res[j].re); - im.push(res[j].im); + for el in res.iter().take(args.order_qcd) { + re.push(el.re); + im.push(el.im); } } // pass on @@ -127,7 +130,10 @@ pub struct QuadQCDargs { pub is_threshold: bool, } -/// empty placeholder function for python callback +/// Empty placeholder function for python callback. +/// +/// # Safety +/// This is the connection back to Python, so we don't know what is on the other side. pub unsafe extern "C" fn my_py( _re_gamma: *const f64, _im_gamma: *const f64, @@ -161,6 +167,9 @@ pub unsafe extern "C" fn my_py( /// /// This is required to make the arguments part of the API, otherwise it won't be added to the compiled /// package (since it does not appear in the signature of `quad_ker_qcd`). +/// +/// # Safety +/// This is the connection from and back to Python, so we don't know what is on the other side. #[no_mangle] pub unsafe extern "C" fn empty_qcd_args() -> QuadQCDargs { QuadQCDargs { diff --git a/crates/eko/src/mellin.rs b/crates/eko/src/mellin.rs index 5afc96f5f..1322bbe08 100644 --- a/crates/eko/src/mellin.rs +++ b/crates/eko/src/mellin.rs @@ -6,14 +6,16 @@ use num::complex::Complex; use std::f64::consts::PI; -#[cfg_attr(doc, katexit::katexit)] /// Talbot inversion path. /// /// Implements the algorithm presented in [\[Abate\]](crate::bib::Abate). -/// $p_{\text{Talbot}}(t) = o + r \cdot ( \theta \cot(\theta) + i\theta)$ with $\theta = \pi(2t-1)$ -/// The default values for the parameters $r,o$ are given by $r = 1/2, o = 0$ for -/// the non-singlet integrals and by $r = \frac{2}{5} \frac{16}{1 - \ln(x)}, o = 1$ -/// for the singlet sector. Note that the non-singlet kernels evolve poles only up to +/// +/// $$p_{\text{Talbot}}(t) = o + r \cdot ( \theta \cot(\theta) + i\theta) ~ \text{with}~ \theta = \pi(2t-1)$$ +/// +/// The default values for the parameters $r,o$ are given by +/// $r = \frac{2}{5} \frac{16}{0.1 - \ln(x)}$ and $o = 0$ for +/// the non-singlet integrals and $o = 1$ for the singlet sector. +/// Note that the non-singlet kernels evolve poles only up to /// $N=0$ whereas the singlet kernels have poles up to $N=1$. pub struct TalbotPath { /// integration variable @@ -27,16 +29,20 @@ pub struct TalbotPath { } impl TalbotPath { - /// Auxilary angle. + /// Auxiliary angle. fn theta(&self) -> f64 { PI * (2.0 * self.t - 1.0) } /// Constructor from parameters. pub fn new(t: f64, logx: f64, is_singlet: bool) -> Self { + // The prescription suggested by Abate for r is 0.4 * M / ( - logx) + // with M the number of accurate digits; Maria Ubiali suggested in her thesis M = 16. + // However, this seems to yield unstable results for the OME in the large x region + // so we add an additional regularization, which makes the path less "edgy" there. Self { t, - r: 0.4 * 16.0 / (1.0 - logx), + r: 0.4 * 16.0 / (0.1 - logx), o: if is_singlet { 1. } else { 0. }, } } diff --git a/crates/ekore/Cargo.toml b/crates/ekore/Cargo.toml index ef8499dba..419bc126a 100644 --- a/crates/ekore/Cargo.toml +++ b/crates/ekore/Cargo.toml @@ -1,14 +1,23 @@ [package] name = "ekore" -version = "0.1.0" -edition = "2021" description = "EKO expressions" -license = "GPL-3.0-or-later" + +authors.workspace = true +readme.workspace = true +categories.workspace = true +edition.workspace = true +keywords.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +[package.metadata.docs.rs] +rustdoc-args = ["--html-in-header", "doc-header.html"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] num = "0.4.1" float-cmp = "0.9.0" -katexit = "0.1.4" hashbrown = "0.14" diff --git a/crates/ekore/doc-header.html b/crates/ekore/doc-header.html new file mode 120000 index 000000000..22282661d --- /dev/null +++ b/crates/ekore/doc-header.html @@ -0,0 +1 @@ +../doc-header.html \ No newline at end of file diff --git a/crates/ekore/refs.bib b/crates/ekore/refs.bib index 3c63b69e7..e8ef02c2b 100644 --- a/crates/ekore/refs.bib +++ b/crates/ekore/refs.bib @@ -50,3 +50,22 @@ @article{Abate journal = {International Journal for Numerical Methods in Engineering}, doi = {10.1002/nme.995} } +@phdthesis{MuselliPhD, + author = "Muselli, Claudio", + title = "{Resummations of Transverse Momentum Distributions}", + doi = "10.13130/muselli-claudio_phd2017-12-01", + school = "Università degli studi di Milano, Dipartimento di Fisica", + year = "2017" +} +@article{Vogt2004ns, + author = "Vogt, A.", + archivePrefix = "arXiv", + doi = "10.1016/j.cpc.2005.03.103", + eprint = "hep-ph/0408244", + journal = "Comput. Phys. Commun.", + pages = "65--92", + reportNumber = "NIKHEF-04-011", + title = "{Efficient evolution of unpolarized and polarized parton distributions with QCD-PEGASUS}", + volume = "170", + year = "2005" +} diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index c2d0fb0d7..dec73bf04 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -1,14 +1,37 @@ //! The unpolarized, space-like anomalous dimensions at various couplings power. +use crate::constants::{PID_NSM, PID_NSP, PID_NSV}; use crate::harmonics::cache::Cache; use num::complex::Complex; use num::Zero; pub mod as1; +pub mod as2; +pub mod as3; /// Compute the tower of the non-singlet anomalous dimensions. -pub fn gamma_ns_qcd(order_qcd: usize, _mode: u16, c: &mut Cache, nf: u8) -> Vec> { +pub fn gamma_ns_qcd(order_qcd: usize, mode: u16, c: &mut Cache, nf: u8) -> Vec> { let mut gamma_ns = vec![Complex::::zero(); order_qcd]; gamma_ns[0] = as1::gamma_ns(c, nf); + // NLO and beyond + if order_qcd >= 2 { + let gamma_ns_1 = match mode { + PID_NSP => as2::gamma_nsp(c, nf), + // To fill the full valence vector in NNLO we need to add gamma_ns^1 explicitly here + PID_NSM | PID_NSV => as2::gamma_nsm(c, nf), + _ => panic!("Unkown non-singlet sector element"), + }; + gamma_ns[1] = gamma_ns_1 + } + // NNLO and beyond + if order_qcd >= 3 { + let gamma_ns_2 = match mode { + PID_NSP => as3::gamma_nsp(c, nf), + PID_NSM => as3::gamma_nsm(c, nf), + PID_NSV => as3::gamma_nsv(c, nf), + _ => panic!("Unkown non-singlet sector element"), + }; + gamma_ns[2] = gamma_ns_2 + } gamma_ns } @@ -22,5 +45,13 @@ pub fn gamma_singlet_qcd(order_qcd: usize, c: &mut Cache, nf: u8) -> Vec<[[Compl order_qcd ]; gamma_S[0] = as1::gamma_singlet(c, nf); + // NLO and beyond + if order_qcd >= 2 { + gamma_S[1] = as2::gamma_singlet(c, nf); + } + // NNLO and beyond + if order_qcd >= 3 { + gamma_S[2] = as3::gamma_singlet(c, nf); + } gamma_S } diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as2.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as2.rs new file mode 100644 index 000000000..b2b16459c --- /dev/null +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as2.rs @@ -0,0 +1,338 @@ +//! NLO QCD + +use ::num::complex::Complex; +use std::f64::consts::LN_2; + +use crate::constants::{CA, CF, TR, ZETA2, ZETA3}; +use crate::harmonics::cache::{Cache, K}; + +/// Compute the valence-like non-singlet anomalous dimension. +/// +/// Implements Eq. (3.6) of [\[Moch:2004pa\]][crate::bib::Moch2004pa]. +pub fn gamma_nsm(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let Sp1m = c.get(K::S1mh); + let Sp2m = c.get(K::S2mh); + let Sp3m = c.get(K::S3mh); + let g3n = c.get(K::G3); + #[rustfmt::skip] + let gqq1m_cfca = 16.0 * g3n + - (144.0 + N * (1.0 + N) * (156.0 + N * (340.0 + N * (655.0 + 51.0 * N * (2.0 + N))))) + / (18.0 * N.powu(3) * (1. + N).powu(3)) + + (-14.666666666666666 + 8.0 / N - 8.0 / (1.0 + N)) * S2 + - (4.0 * Sp2m) / (N + N.powu(2)) + + S1 * (29.77777777777778 + 16.0 / N.powu(2) - 16.0 * S2 + 8.0 * Sp2m) + + 2.0 * Sp3m + + 10.0 * ZETA3 + + ZETA2 * (16.0 * S1 - 16.0 * Sp1m - (16.0 * (1. + N * LN_2)) / N); + #[rustfmt::skip] + let gqq1m_cfcf = -32. * g3n + + (24. - N * (-32. + 3. * N * (-8. + N * (3. + N) * (3. + N.powu(2))))) + / (2. * N.powu(3) * (1. + N).powu(3)) + + (12. - 8. / N + 8. / (1. + N)) * S2 + + S1 * (-24. / N.powu(2) - 8. / (1. + N).powu(2) + 16. * S2 - 16. * Sp2m) + + (8. * Sp2m) / (N + N.powu(2)) + - 4. * Sp3m + - 20. * ZETA3 + + ZETA2 * (-32. * S1 + 32. * Sp1m + 32. * (1. / N + LN_2)); + #[rustfmt::skip] + let gqq1m_cfnf = (-12. + N * (20. + N * (47. + 3. * N * (2. + N)))) + / (9. * N.powu(2) * (1. + N).powu(2)) + - (40. * S1) / 9. + + (8. * S2) / 3.; + + CF * (CA * gqq1m_cfca + CF * gqq1m_cfcf + 2.0 * TR * (nf as f64) * gqq1m_cfnf) +} + +/// Compute the singlet-like non-singlet anomalous dimension. +/// +/// Implements Eq. (3.5) of [\[Moch:2004pa\]][crate::bib::Moch2004pa]. +pub fn gamma_nsp(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let Sp1p = c.get(K::S1h); + let Sp2p = c.get(K::S2h); + let Sp3p = c.get(K::S3h); + let g3n = c.get(K::G3); + #[rustfmt::skip] + let gqq1p_cfca = -16. * g3n + + (132. - N * (340. + N * (655. + 51. * N * (2. + N)))) + / (18. * N.powu(2) * (1. + N).powu(2)) + + (-14.666666666666666 + 8. / N - 8. / (1. + N)) * S2 + - (4. * Sp2p) / (N + N.powu(2)) + + S1 * (29.77777777777778 - 16. / N.powu(2) - 16. * S2 + 8. * Sp2p) + + 2. * Sp3p + + 10. * ZETA3 + + ZETA2 * (16. * S1 - 16. * Sp1p + 16. * (1. / N - LN_2)); + #[rustfmt::skip] + let gqq1p_cfcf = 32. * g3n + - (8. + N * (32. + N * (40. + 3. * N * (3. + N) * (3. + N.powu(2))))) + / (2. * N.powu(3) * (1. + N).powu(3)) + + (12. - 8. / N + 8. / (1. + N)) * S2 + + S1 * (40. / N.powu(2) - 8. / (1. + N).powu(2) + 16. * S2 - 16. * Sp2p) + + (8. * Sp2p) / (N + N.powu(2)) + - 4. * Sp3p + - 20. * ZETA3 + + ZETA2 * (-32. * S1 + 32. * Sp1p + 32. * (-(1. / N) + LN_2)); + #[rustfmt::skip] + let gqq1p_cfnf = (-12. + N * (20. + N * (47. + 3. * N * (2. + N)))) + / (9. * N.powu(2) * (1. + N).powu(2)) + - (40. * S1) / 9. + + (8. * S2) / 3.; + + CF * (CA * gqq1p_cfca + CF * gqq1p_cfcf + 2.0 * TR * (nf as f64) * gqq1p_cfnf) +} + +/// Compute the pure-singlet quark-quark anomalous dimension. +/// +/// Implements Eq. (3.6) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_ps(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let gqqps1_nfcf = (-4. * (2. + N * (5. + N)) * (4. + N * (4. + N * (7. + 5. * N)))) + / ((-1. + N) * N.powu(3) * (1. + N).powu(3) * (2. + N).powu(2)); + 2.0 * TR * (nf as f64) * CF * gqqps1_nfcf +} + +/// Compute the quark-gluon singlet anomalous dimension. +/// +/// Implements Eq. (3.7) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_qg(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let Sp2p = c.get(K::S2h); + #[rustfmt::skip] + let gqg1_nfca = (-4. + * (16. + + N * (64. + + N * (104. + + N * (128. + N * (85. + N * (36. + N * (25. + N * (15. + N * (6. + N)))))))))) + / ((-1. + N) * N.powu(3) * (1. + N).powu(3) * (2. + N).powu(3)) + - (16. * (3. + 2. * N) * S1) / (2. + 3. * N + N.powu(2)).powu(2) + + (4. * (2. + N + N.powu(2)) * S1.powu(2)) / (N * (2. + 3. * N + N.powu(2))) + - (4. * (2. + N + N.powu(2)) * S2) / (N * (2. + 3. * N + N.powu(2))) + + (4. * (2. + N + N.powu(2)) * Sp2p) / (N * (2. + 3. * N + N.powu(2))); + #[rustfmt::skip] + let gqg1_nfcf = (-2. * (4. + N * (8. + N * (1. + N) * (25. + N * (26. + 5. * N * (2. + N)))))) + / (N.powu(3) * (1. + N).powu(3) * (2. + N)) + + (8. * S1) / N.powu(2) + - (4. * (2. + N + N.powu(2)) * S1.powu(2)) / (N * (2. + 3. * N + N.powu(2))) + + (4. * (2. + N + N.powu(2)) * S2) / (N * (2. + 3. * N + N.powu(2))); + 2.0 * TR * (nf as f64) * (CA * gqg1_nfca + CF * gqg1_nfcf) +} + +/// Compute the gluon-quark singlet anomalous dimension. +/// +/// Implements Eq. (3.8) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_gq(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let Sp2p = c.get(K::S2h); + #[rustfmt::skip] + let ggq1_cfcf = (-8. + + 2. * N * (-12. + N * (-1. + N * (28. + N * (43. + 6. * N * (5. + 2. * N)))))) + / ((-1. + N) * N.powu(3) * (1. + N).powu(3)) + - (4. * (10. + N * (17. + N * (8. + 5. * N))) * S1) / ((-1. + N) * N * (1. + N).powu(2)) + + (4. * (2. + N + N.powu(2)) * S1.powu(2)) / (N * (-1. + N.powu(2))) + + (4. * (2. + N + N.powu(2)) * S2) / (N * (-1. + N.powu(2))); + #[rustfmt::skip] + let ggq1_cfca = (-4. + * (144. + + N * (432. + + N * (-152. + + N * (-1304. + + N * (-1031. + + N * (695. + N * (1678. + N * (1400. + N * (621. + 109. * N)))))))))) + / (9. * N.powu(3) * (1. + N).powu(3) * (-2. + N + N.powu(2)).powu(2)) + + (4. * (-12. + N * (-22. + 41. * N + 17. * N.powu(3))) * S1) + / (3. * (-1. + N).powu(2) * N.powu(2) * (1. + N)) + + ((8. + 4. * N + 4. * N.powu(2)) * S1.powu(2)) / (N - N.powu(3)) + + ((8. + 4. * N + 4. * N.powu(2)) * S2) / (N - N.powu(3)) + + (4. * (2. + N + N.powu(2)) * Sp2p) / (N * (-1. + N.powu(2))); + #[rustfmt::skip] + let ggq1_cfnf = (8. * (16. + N * (27. + N * (13. + 8. * N)))) + / (9. * (-1. + N) * N * (1. + N).powu(2)) + - (8. * (2. + N + N.powu(2)) * S1) / (3. * N * (-1. + N.powu(2))); + CF * (CA * ggq1_cfca + CF * ggq1_cfcf + 2.0 * TR * (nf as f64) * ggq1_cfnf) +} + +/// Compute the gluon-gluon singlet anomalous dimension. +/// +/// Implements Eq. (3.9) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_gg(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let Sp1p = c.get(K::S1h); + let Sp2p = c.get(K::S2h); + let Sp3p = c.get(K::S3h); + let g3n = c.get(K::G3); + #[rustfmt::skip] + let ggg1_caca = 16. * g3n + - (2. + * (576. + + N * (1488. + + N * (560. + + N * (-1248. + + N * (-1384. + + N * (1663. + + N * (4514. + + N * (4744. + + N * (3030. + + N * (1225. + 48. * N * (7. + N)))))))))))) + / (9. * (-1. + N).powu(2) * N.powu(3) * (1. + N).powu(3) * (2. + N).powu(3)) + + S1 * (29.77777777777778 + 16. / (-1. + N).powu(2) + 16. / (1. + N).powu(2) + - 16. / (2. + N).powu(2) + - 8. * Sp2p) + + (16. * (1. + N + N.powu(2)) * Sp2p) / (N * (1. + N) * (-2. + N + N.powu(2))) + - 2. * Sp3p + - 10. * ZETA3 + + ZETA2 * (-16. * S1 + 16. * Sp1p + 16. * (-(1. / N) + LN_2)); + #[rustfmt::skip] + let ggg1_canf = (8. * (6. + N * (1. + N) * (28. + N * (1. + N) * (13. + 3. * N * (1. + N))))) + / (9. * N.powu(2) * (1. + N).powu(2) * (-2. + N + N.powu(2))) + - (40. * S1) / 9.; + #[rustfmt::skip] + let ggg1_cfnf = (2. + * (-8. + + N * (-8. + + N * (-10. + N * (-22. + N * (-3. + N * (6. + N * (8. + N * (4. + N))))))))) + / (N.powu(3) * (1. + N).powu(3) * (-2. + N + N.powu(2))); + + CA * CA * ggg1_caca + 2.0 * TR * (nf as f64) * (CA * ggg1_canf + CF * ggg1_cfnf) +} + +/// Compute the singlet anomalous dimension matrix. +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { + let gamma_qq = gamma_nsp(c, nf) + gamma_ps(c, nf); + [ + [gamma_qq, gamma_qg(c, nf)], + [gamma_gq(c, nf), gamma_gg(c, nf)], + ] +} + +#[cfg(test)] +mod tests { + use crate::cmplx; + use crate::{anomalous_dimensions::unpolarized::spacelike::as2::*, harmonics::cache::Cache}; + use float_cmp::assert_approx_eq; + use num::complex::Complex; + use num::traits::Pow; + use std::f64::consts::PI; + + const NF: u8 = 5; + + #[test] + fn physical_constraints() { + // number conservation + let mut c = Cache::new(cmplx![1., 0.]); + assert_approx_eq!(f64, gamma_nsm(&mut c, NF).re, 0.0, epsilon = 2e-6); + + // momentum conservation + let mut c = Cache::new(cmplx![2., 0.]); + let gS1 = gamma_singlet(&mut c, NF); + + // gluon momentum conservation + assert_approx_eq!(f64, (gS1[0][1] + gS1[1][1]).re, 0.0, epsilon = 4e-5); + // quark momentum conservation + assert_approx_eq!(f64, (gS1[0][0] + gS1[1][0]).re, 0.0, epsilon = 2e-6); + } + + #[test] + fn N2() { + // reference values are obtained from MMa + let mut c = Cache::new(cmplx![2., 0.]); + + // ns+ + assert_approx_eq!( + f64, + gamma_nsp(&mut c, NF).re, + (-112.0 * CF + 376.0 * CA - 64.0 * (NF as f64)) * CF / 27.0, + epsilon = 2e-6 + ); + + // ns- + let check = ((34.0 / 27.0 * (-47.0 + 6. * PI.pow(2)) - 16.0 * ZETA3) * CF + + (373.0 / 9.0 - 34.0 * PI.pow(2) / 9.0 + 8.0 * ZETA3) * CA + - 64.0 * (NF as f64) / 27.0) + * CF; + assert_approx_eq!(f64, gamma_nsm(&mut c, NF).re, check, epsilon = 2e-6); + + // singlet sector + let gS1 = gamma_singlet(&mut c, NF); + // ps + assert_approx_eq!( + f64, + gamma_ps(&mut c, NF).re, + -40.0 * CF * (NF as f64) / 27.0 + ); + // qg + assert_approx_eq!( + f64, + gS1[0][1].re, + (-74.0 * CF - 35.0 * CA) * (NF as f64) / 27.0 + ); + // gq + assert_approx_eq!( + f64, + gS1[1][0].re, + (112.0 * CF - 376.0 * CA + 104.0 * (NF as f64)) * CF / 27.0, + epsilon = 1e-13 + ); + } + + #[test] + fn N3() { + let mut c = Cache::new(cmplx![3., 0.]); + // ns+ + let check = ((-34487.0 / 432.0 + 86.0 * PI.pow(2) / 9.0 - 16.0 * ZETA3) * CF + + (459.0 / 8.0 - 43.0 * PI.pow(2) / 9.0 + 8.0 * ZETA3) * CA + - 415.0 * (NF as f64) / 108.0) + * CF; + assert_approx_eq!(f64, gamma_nsp(&mut c, NF).re, check, epsilon = 2e-6); + + // singlet sector + let gS1 = gamma_singlet(&mut c, NF); + // ps + assert_approx_eq!( + f64, + gamma_ps(&mut c, NF).re, + -1391.0 * CF * (NF as f64) / 5400.0 + ); + // gq + assert_approx_eq!( + f64, + gS1[1][0].re, + (973.0 / 432.0 * CF + + (2801.0 / 5400.0 - 7.0 * PI.pow(2) / 9.0) * CA + + 61.0 / 54.0 * (NF as f64)) + * CF + ); + // gg + assert_approx_eq!( + f64, + gS1[1][1].re, + (-79909.0 / 3375.0 + 194.0 * PI.pow(2) / 45.0 - 8.0 * ZETA3) * CA.pow(2) + - 967.0 / 270.0 * CA * (NF as f64) + + 541.0 / 216.0 * CF * (NF as f64), + epsilon = 3e-5 + ); + } + + #[test] + fn N4() { + let mut c = Cache::new(cmplx![4., 0.]); + // singlet sector + let gS1 = gamma_singlet(&mut c, NF); + // qg + assert_approx_eq!( + f64, + gS1[0][1].re, + (-56317.0 / 18000.0 * CF + 16387.0 / 9000.0 * CA) * (NF as f64), + epsilon = 1e-14 + ) + } +} diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as3.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as3.rs new file mode 100644 index 000000000..14354f736 --- /dev/null +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as3.rs @@ -0,0 +1,455 @@ +//! NNLO QCD + +use ::num::complex::Complex; +use num::traits::Pow; + +use crate::cmplx; +use crate::constants::{ZETA2, ZETA3}; +use crate::harmonics::cache::{Cache, K}; + +/// Compute the valence-like non-singlet anomalous dimension. +/// +/// Implements Eq. (3.8) of [\[Moch:2004pa\]][crate::bib::Moch2004pa]. +pub fn gamma_nsm(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + let E1 = S1 / N.powu(2) + (S2 - ZETA2) / N; + let E2 = 2.0 * (-S1 / N.powu(3) + (ZETA2 - S2) / N.powu(2) - (S3 - ZETA3) / N); + + #[rustfmt::skip] + let pm2 = + -1174.898 * (S1 - 1.0 / N) + + 1295.470 + - 714.1 * S1 / N + - 433.2 / (N + 3.0) + + 297.0 / (N + 2.0) + - 3505.0 / (N + 1.0) + + 1860.2 / N + - 1465.2 / N.powu(2) + + 399.2 * 2.0 / N.powu(3) + - 320.0 / 9.0 * 6.0 / N.powu(4) + + 116.0 / 81.0 * 24.0 / N.powu(5) + + 684.0 * E1 + + 251.2 * E2; + + #[rustfmt::skip] + let pm2_nf = + 183.187 * (S1 - 1.0 / N) + - 173.933 + + 5120./ 81.0 * S1 / N + + 34.76 / (N + 3.0) + + 77.89 / (N + 2.0) + + 406.5 / (N + 1.0) + - 216.62 / N + + 172.69 / N.powu(2) + - 3216.0 / 81.0 * 2.0 / N.powu(3) + + 256.0 / 81.0 * 6.0 / N.powu(4) + - 65.43 * E1 + + 1.136 * 6.0 / (N + 1.0).powu(4); + + #[rustfmt::skip] + let pf2_nfnf = + -( + 17.0 / 72.0 + - 2.0 / 27.0 * S1 + - 10.0 / 27.0 * S2 + + 2.0 / 9.0 * S3 + - (12.0 * N.powu(4) + 2.0 * N.powu(3) - 12.0 * N.powu(2) - 2.0 * N + 3.0) + / (27.0 * N.powu(3) * (N + 1.0).powu(3)) + )* 32.0 / 3.0; + + let result = pm2 + (nf as f64) * pm2_nf + (nf as f64).pow(2) * pf2_nfnf; + -1. * result +} + +/// Compute the singlet-like non-singlet anomalous dimension. +/// +/// Implements Eq. (3.7) of [\[Moch:2004pa\]][crate::bib::Moch2004pa]. +pub fn gamma_nsp(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + let E1 = S1 / N.powu(2) + (S2 - ZETA2) / N; + let E2 = 2.0 * (-S1 / N.powu(3) + (ZETA2 - S2) / N.powu(2) - (S3 - ZETA3) / N); + + #[rustfmt::skip] + let pp2 = + -1174.898 * (S1 - 1.0 / N) + + 1295.384 + - 714.1 * S1 / N + - 522.1 / (N + 3.0) + + 243.6 / (N + 2.0) + - 3135.0 / (N + 1.0) + + 1641.1 / N + - 1258.0 / N.powu(2) + + 294.9 * 2.0 / N.powu(3) + - 800. / 27.0 * 6.0 / N.powu(4) + + 128. / 81.0 * 24.0 / N.powu(5) + + 563.9 * E1 + + 256.8 * E2; + + #[rustfmt::skip] + let pp2_nf = + 183.187 * (S1 - 1.0 / N) + - 173.924 + + 5120. / 81.0 * S1 / N + + 44.79 / (N + 3.0) + + 72.94 / (N + 2.0) + + 381.1 / (N + 1.0) + - 197.0 / N + + 152.6 / N.powu(2) + - 2608.0 / 81.0 * 2.0 / N.powu(3) + + 192.0 / 81.0 * 6.0 / N.powu(4) + - 56.66 * E1 + + 1.497 * 6.0 / (N + 1.0).powu(4); + + #[rustfmt::skip] + let pf2_nfnf = + -( + 17.0 / 72.0 + - 2.0 / 27.0 * S1 + - 10.0 / 27.0 * S2 + + 2.0 / 9.0 * S3 + - (12.0 * N.powu(4) + 2.0 * N.powu(3) - 12.0 * N.powu(2) - 2.0 * N + 3.0) + / (27.0 * N.powu(3) * (N + 1.0).powu(3)) + )* 32.0/ 3.0; + + let result = pp2 + (nf as f64) * pp2_nf + (nf as f64).pow(2) * pf2_nfnf; + -1. * result +} + +/// Compute the valence non-singlet anomalous dimension. +/// +/// Implements Eq. (3.9) of [\[Moch:2004pa\]][crate::bib::Moch2004pa]. +pub fn gamma_nsv(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + let E1 = S1 / N.powu(2) + (S2 - ZETA2) / N; + let E2 = 2.0 * (-S1 / N.powu(3) + (ZETA2 - S2) / N.powu(2) - (S3 - ZETA3) / N); + let B11 = -(S1 + 1.0 / (N + 1.0)) / (N + 1.0); + let B12 = -(S1 + 1.0 / (N + 1.0) + 1.0 / (N + 2.0)) / (N + 2.0); + + let B1M = if N.im.abs() < 1.0e-5 && (N - 1.0).re.abs() < 1.0e-5 { + cmplx![-ZETA2, 0.] + } else { + -(S1 - 1.0 / N) / (N - 1.0) + }; + + #[rustfmt::skip] + let ps2 = -( + -163.9 * (B1M + S1 / N) + - 7.208 * (B11 - B12) + + 4.82 * (1.0 / (N + 3.0) - 1.0 / (N + 4.0)) + - 43.12 * (1.0 / (N + 2.0) - 1.0 / (N + 3.0)) + + 44.51 * (1.0 / (N + 1.0) - 1.0 / (N + 2.0)) + + 151.49 * (1.0 / N - 1.0 / (N + 1.0)) + - 178.04 / N.powu(2) + + 6.892 * 2.0 / N.powu(3) + - 40.0 / 27.0 * (-2.0 * 6.0 / N.powu(4) - 24.0 / N.powu(5)) + - 173.1 * E1 + + 46.18 * E2 + ); + + gamma_nsm(c, nf) + (nf as f64) * ps2 +} + +/// Compute the pure-singlet quark-quark anomalous dimension. +/// +/// Implements Eq. (3.10) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_ps(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + + let E1 = S1 / N.powu(2) + (S2 - ZETA2) / N; + let E11 = (S1 + 1.0 / (N + 1.0)) / (N + 1.0).powu(2) + + (S2 + 1.0 / (N + 1.0).powu(2) - ZETA2) / (N + 1.0); + let B21 = ((S1 + 1.0 / (N + 1.0)).powu(2) + S2 + 1.0 / (N + 1.0).powu(2)) / (N + 1.0); + let B3 = -(S1.powu(3) + 3.0 * S1 * S2 + 2.0 * S3) / N; + + #[rustfmt::skip] + let B31 = -( + (S1 + 1.0 / (N + 1.0)).powu(3) + + 3.0 * (S1 + 1.0 / (N + 1.0)) * (S2 + 1.0 / (N + 1.0).powu(2)) + + 2.0 * (S3 + 1.0 / (N + 1.0).powu(3)) + ) / (N + 1.0); + + #[rustfmt::skip] + let ps1 = + -3584.0 / 27.0 * (-1.0 / (N - 1.0).powu(2) + 1.0 / N.powu(2)) + - 506.0 * (1.0 / (N - 1.0) - 1.0 / N) + + 160.0 / 27.0 * (24.0 / N.powu(5) - 24.0 / (N + 1.0).powu(5)) + - 400.0 / 9.0 * (-6.0 / N.powu(4) + 6.0 / (N + 1.0).powu(4)) + + 131.4 * (2.0 / N.powu(3) - 2.0 / (N + 1.0).powu(3)) + - 661.6 * (-1.0 / N.powu(2) + 1.0 / (N + 1.0).powu(2)) + - 5.926 * (B3 - B31) + - 9.751 * ((S1.powu(2) + S2) / N - B21) + - 72.11 * (-S1 / N + (S1 + 1.0 / (N + 1.0)) / (N + 1.0)) + + 177.4 * (1.0 / N - 1.0 / (N + 1.0)) + + 392.9 * (1.0 / (N + 1.0) - 1.0 / (N + 2.0)) + - 101.4 * (1.0 / (N + 2.0) - 1.0 / (N + 3.0)) + - 57.04 * (E1 - E11); + + #[rustfmt::skip] + let ps2 = + 256.0 / 81.0 * (1.0 / (N - 1.0) - 1.0 / N) + + 32.0 / 27.0 * (-6.0 / N.powu(4) + 6.0 / (N + 1.0).powu(4)) + + 17.89 * (2.0 / N.powu(3) - 2.0 / (N + 1.0).powu(3)) + + 61.75 * (-1.0 / N.powu(2) + 1.0 / (N + 1.0).powu(2)) + + 1.778 * ((S1.powu(2) + S2) / N - B21) + + 5.944 * (-S1 / N + (S1 + 1.0 / (N + 1.0)) / (N + 1.0)) + + 100.1 * (1.0 / N - 1.0 / (N + 1.0)) + - 125.2 * (1.0 / (N + 1.0) - 1.0 / (N + 2.0)) + + 49.26 * (1.0 / (N + 2.0) - 1.0 / (N + 3.0)) + - 12.59 * (1.0 / (N + 3.0) - 1.0 / (N + 4.0)) + - 1.889 * (E1 - E11); + + let result = (nf as f64) * ps1 + (nf as f64).pow(2) * ps2; + -1.0 * result +} + +/// Compute the quark-gluon singlet anomalous dimension. +/// +/// Implements Eq. (3.11) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_qg(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + let S4 = c.get(K::S4); + + let E1 = S1 / N.powu(2) + (S2 - ZETA2) / N; + let E2 = 2.0 * (-S1 / N.powu(3) + (ZETA2 - S2) / N.powu(2) - (S3 - ZETA3) / N); + let B3 = -(S1.powu(3) + 3.0 * S1 * S2 + 2.0 * S3) / N; + let B4 = (S1.powu(4) + 6.0 * S1.powu(2) * S2 + 8.0 * S1 * S3 + 3.0 * S2.powu(2) + 6.0 * S4) / N; + + #[rustfmt::skip] + let qg1 = + 896.0 / 3.0 / (N - 1.0).powu(2) + - 1268.3 / (N - 1.0) + + 536.0 / 27.0 * 24.0 / N.powu(5) + + 44.0 / 3.0 * 6.0 / N.powu(4) + + 881.5 * 2.0 / N.powu(3) + - 424.9 / N.powu(2) + + 100.0 / 27.0 * B4 + - 70.0 / 9.0 * B3 + - 120.5 * (S1.powu(2) + S2) / N + - 104.42 * S1 / N + + 2522.0 / N + - 3316.0 / (N + 1.0) + + 2126.0 / (N + 2.0) + + 1823.0 * E1 + - 25.22 * E2 + + 252.5 * 6.0 / (N + 1.0).powu(4); + + #[rustfmt::skip] + let qg2 = + 1112.0 / 243.0 / (N - 1.0) + - 16.0 / 9.0 * 24.0 / N.powu(5) + + 376.0 / 27.0 * 6.0 / N.powu(4) + - 90.8 * 2.0 / N.powu(3) + + 254.0 / N.powu(2) + + 20.0 / 27.0 * B3 + + 200.0 / 27.0 * (S1.powu(2) + S2) / N + + 5.496 * S1 / N + - 252.0 / N + + 158.0 / (N + 1.0) + + 145.4 / (N + 2.0) + - 139.28 / (N + 3.0) + - 53.09 * E1 + - 80.616 * E2 + - 98.07 * 2.0 / (N + 1.0).powu(3) + - 11.70 * 6.0 / (N + 1.0).powu(4); + + let result = (nf as f64) * qg1 + (nf as f64).pow(2) * qg2; + -1.0 * result +} + +/// Compute the gluon-quark singlet anomalous dimension. +/// +/// Implements Eq. (3.12) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_gq(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + let S4 = c.get(K::S4); + + let E1 = S1 / N.powu(2) + (S2 - ZETA2) / N; + let E2 = 2.0 * (-S1 / N.powu(3) + (ZETA2 - S2) / N.powu(2) - (S3 - ZETA3) / N); + let B21 = ((S1 + 1.0 / (N + 1.0)).powu(2) + S2 + 1.0 / (N + 1.0).powu(2)) / (N + 1.0); + let B3 = -(S1.powu(3) + 3.0 * S1 * S2 + 2.0 * S3) / N; + let B4 = (S1.powu(4) + 6.0 * S1.powu(2) * S2 + 8.0 * S1 * S3 + 3.0 * S2.powu(2) + 6.0 * S4) / N; + + #[rustfmt::skip] + let gq0 = + -1189.3 * 1.0 / (N - 1.0).powu(2) + + 6163.1 / (N - 1.0) + - 4288.0 / 81.0 * 24.0 / N.powu(5) + - 1568.0 / 9.0 * 6.0 / N.powu(4) + - 1794.0 * 2.0 / N.powu(3) + - 4033.0 * 1.0 / N.powu(2) + + 400.0 / 81.0 * B4 + + 2200.0 / 27.0 * B3 + + 606.3 * (S1.powu(2) + S2) / N + - 2193.0 * S1 / N + - 4307.0 / N + + 489.3 / (N + 1.0) + + 1452.0 / (N + 2.0) + + 146.0 / (N + 3.0) + - 447.3 * E2 + - 972.9 * 2.0 / (N + 1.0).powu(3); + + #[rustfmt::skip] + let gq1 = + -71.082 / (N - 1.0).powu(2) + - 46.41 / (N - 1.0) + + 128.0 / 27.0 * 24.0 / N.powu(5) + - 704. / 81.0 * 6.0 / N.powu(4) + + 20.39 * 2.0 / N.powu(3) + - 174.8 * 1.0 / N.powu(2) + - 400.0 / 81.0 * B3 + - 68.069 * (S1.powu(2) + S2) / N + + 296.7 * S1 / N + - 183.8 / N + + 33.35 / (N + 1.0) + - 277.9 / (N + 2.0) + + 108.6 * 2.0 / (N + 1.0).powu(3) + - 49.68 * E1; + + #[rustfmt::skip] + let gq2 = ( + 64.0 * (-1.0 / (N - 1.0) + 1.0 / N + 2.0 / (N + 1.0)) + + 320.0 + * ( + -(S1 - 1.0 / N) / (N - 1.0) + + S1 / N + - 0.8 * (S1 + 1.0 / (N + 1.0)) / (N + 1.0) + ) + + 96.0 + * ( + ((S1 - 1.0 / N).powu(2) + S2 - 1.0 / N.powu(2)) / (N - 1.0) + - (S1.powu(2) + S2) / N + + 0.5 * B21 + ) + ) / 27.0; + + let result = gq0 + (nf as f64) * gq1 + (nf as f64).pow(2) * gq2; + -1.0 * result +} + +/// Compute the gluon-quark singlet anomalous dimension. +/// +/// Implements Eq. (3.13) of [\[Vogt:2004mw\]][crate::bib::Vogt2004mw]. +pub fn gamma_gg(c: &mut Cache, nf: u8) -> Complex { + let N = c.n; + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + + let E1 = S1 / N.powu(2) + (S2 - ZETA2) / N; + let E11 = (S1 + 1.0 / (N + 1.0)) / (N + 1.0).powu(2) + + (S2 + 1.0 / (N + 1.0).powu(2) - ZETA2) / (N + 1.0); + let E2 = 2.0 * (-S1 / N.powu(3) + (ZETA2 - S2) / N.powu(2) - (S3 - ZETA3) / N); + + #[rustfmt::skip] + let gg0 = + -2675.8 / (N - 1.0).powu(2) + + 14214.0 / (N - 1.0) + - 144.0 * 24.0 / N.powu(5) + - 72.0 * 6.0 / N.powu(4) + - 7471.0 * 2.0 / N.powu(3) + - 274.4 / N.powu(2) + - 20852.0 / N + + 3968.0 / (N + 1.0) + - 3363.0 / (N + 2.0) + + 4848.0 / (N + 3.0) + + 7305.0 * E1 + + 8757.0 * E2 + - 3589.0 * S1 / N + + 4425.894 + - 2643.521 * (S1 - 1.0 / N); + + #[rustfmt::skip] + let gg1 = + -157.27 / (N - 1.0).powu(2) + + 182.96 / (N - 1.0) + + 512.0 / 27.0 * 24.0 / N.powu(5) + - 832.0 / 9.0 * 6.0 / N.powu(4) + + 491.3 * 2.0 / N.powu(3) + - 1541.0 / N.powu(2) + - 350.2 / N + + 755.7 / (N + 1.0) + - 713.8 / (N + 2.0) + + 559.3 / (N + 3.0) + + 26.15 * E1 + - 808.7 * E2 + + 320.0 * S1 / N + - 528.723 + + 412.172 * (S1 - 1.0 / N); + + #[rustfmt::skip] + let gg2 = + -680.0 / 243.0 / (N - 1.0) + + 32.0 / 27.0 * 6.0 / N.powu(4) + + 9.680 * 2.0 / N.powu(3) + + 3.422 / N.powu(2) + - 13.878 / N + + 153.4 / (N + 1.0) + - 187.7 / (N + 2.0) + + 52.75 / (N + 3.0) + - 115.6 * E1 + + 85.25 * E11 + - 63.23 * E2 + + 6.4630 + + 16.0 / 9.0 * (S1 - 1.0 / N); + + let result = gg0 + (nf as f64) * gg1 + (nf as f64).pow(2) * gg2; + -1.0 * result +} + +/// Compute the singlet anomalous dimension matrix. +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { + let gamma_qq = gamma_nsp(c, nf) + gamma_ps(c, nf); + [ + [gamma_qq, gamma_qg(c, nf)], + [gamma_gq(c, nf), gamma_gg(c, nf)], + ] +} + +#[cfg(test)] +mod tests { + use crate::cmplx; + use crate::{anomalous_dimensions::unpolarized::spacelike::as3::*, harmonics::cache::Cache}; + use float_cmp::assert_approx_eq; + use num::complex::Complex; + + const NF: u8 = 5; + + #[test] + fn physical_constraints() { + // number conservation + let mut c = Cache::new(cmplx![1., 0.]); + assert_approx_eq!(f64, gamma_nsv(&mut c, NF).re, -0.000960586, epsilon = 3e-7); + assert_approx_eq!(f64, gamma_nsm(&mut c, NF).re, 0.000594225, epsilon = 6e-7); + + let mut c = Cache::new(cmplx![2., 0.]); + let gS2 = gamma_singlet(&mut c, NF); + // gluon momentum conservation + assert_approx_eq!(f64, (gS2[0][1] + gS2[1][1]).re, -0.00388726, epsilon = 2e-6); + // quark momentum conservation + assert_approx_eq!(f64, (gS2[0][0] + gS2[1][0]).re, 0.00169375, epsilon = 2e-6); + } + + #[test] + fn N2() { + let mut c = Cache::new(cmplx![2., 0.]); + assert_approx_eq!(f64, gamma_nsv(&mut c, NF).re, 188.325593, epsilon = 3e-7); + } +} diff --git a/crates/ekore/src/bib.rs b/crates/ekore/src/bib.rs index c62f16d02..75da707bb 100644 --- a/crates/ekore/src/bib.rs +++ b/crates/ekore/src/bib.rs @@ -1,5 +1,6 @@ -//! List of References (autogenerated on 2023-11-29T18:07:41.518255). +//! List of References (autogenerated on 2024-05-30T12:57:15.459698). +#[allow(non_snake_case)] /// The Three loop splitting functions in QCD: The Nonsinglet case /// /// Moch, S. and Vermaseren, J. A. M. and Vogt, A. @@ -11,6 +12,7 @@ /// DOI: [10.1016/j.nuclphysb.2004.03.030](https:dx.doi.org/10.1016/j.nuclphysb.2004.03.030) pub fn Moch2004pa() {} +#[allow(non_snake_case)] /// The Three-loop splitting functions in QCD: The Singlet case /// /// Vogt, A. and Moch, S. and Vermaseren, J. A. M. @@ -22,6 +24,7 @@ pub fn Moch2004pa() {} /// DOI: [10.1016/j.nuclphysb.2004.04.024](https:dx.doi.org/10.1016/j.nuclphysb.2004.04.024) pub fn Vogt2004mw() {} +#[allow(non_snake_case)] /// Programs for computing the logarithm of the gamma function, and the digamma function, for complex argument /// /// K.S. Kölbig @@ -33,6 +36,7 @@ pub fn Vogt2004mw() {} /// DOI: [https://doi.org/10.1016/0010-4655(72)90012-4](https://doi.org/10.1016/0010-4655(72)90012-4) pub fn KOLBIG1972221() {} +#[allow(non_snake_case)] /// Multi‐precision Laplace transform inversion /// /// Abate, J. and Valkó, P. @@ -43,3 +47,27 @@ pub fn KOLBIG1972221() {} /// /// DOI: [10.1002/nme.995](https:dx.doi.org/10.1002/nme.995) pub fn Abate() {} + +#[allow(non_snake_case)] +/// Resummations of Transverse Momentum Distributions +/// +/// Muselli, Claudio +/// +/// Published as PhD thesis at Università degli studi di Milano, Dipartimento di Fisica (2017) +/// +/// +/// +/// DOI: [10.13130/muselli-claudio_phd2017-12-01](https:dx.doi.org/10.13130/muselli-claudio_phd2017-12-01) +pub fn MuselliPhD() {} + +#[allow(non_snake_case)] +/// Efficient evolution of unpolarized and polarized parton distributions with QCD-PEGASUS +/// +/// Vogt, A. +/// +/// Published in: Comput. Phys. Commun. 170 (2005), 65--92 +/// +/// e-Print: [hep-ph/0408244](https://arxiv.org/abs/hep-ph/0408244) +/// +/// DOI: [10.1016/j.cpc.2005.03.103](https:dx.doi.org/10.1016/j.cpc.2005.03.103) +pub fn Vogt2004ns() {} diff --git a/crates/ekore/src/constants.rs b/crates/ekore/src/constants.rs index 3cdd13a15..c824bdf5a 100644 --- a/crates/ekore/src/constants.rs +++ b/crates/ekore/src/constants.rs @@ -1,25 +1,43 @@ //! Global constants. -#[cfg_attr(doc, katexit::katexit)] /// The number of colors. /// /// Defaults to $N_C = 3$. pub const NC: u8 = 3; -#[cfg_attr(doc, katexit::katexit)] /// The normalization of fundamental generators. /// /// Defaults to $T_R = 1/2$. pub const TR: f64 = 1.0 / 2.0; -#[cfg_attr(doc, katexit::katexit)] /// Second Casimir constant in the adjoint representation. /// /// Defaults to $C_A = N_C = 3$. pub const CA: f64 = NC as f64; -#[cfg_attr(doc, katexit::katexit)] /// Second Casimir constant in the fundamental representation. /// /// Defaults to $C_F = \frac{N_C^2-1}{2N_C} = 4/3$. pub const CF: f64 = ((NC * NC - 1) as f64) / ((2 * NC) as f64); + +/// Riemann zeta function at z = 2. +/// +/// $\zeta(2) = \pi^2 / 6$. +pub const ZETA2: f64 = 1.6449340668482264; + +/// Riemann zeta function at z = 3. +pub const ZETA3: f64 = 1.2020569031595942; + +/// Riemann zeta function at z = 4. +/// +/// $\zeta(4) = \pi^4 / 90$. +pub const ZETA4: f64 = 1.082323233711138; + +/// singlet-like non-singlet PID +pub const PID_NSP: u16 = 10101; + +/// valence-like non-singlet PID +pub const PID_NSM: u16 = 10201; + +/// non-singlet all-valence PID +pub const PID_NSV: u16 = 10200; diff --git a/crates/ekore/src/harmonics.rs b/crates/ekore/src/harmonics.rs index b829060fc..a8a3b3241 100644 --- a/crates/ekore/src/harmonics.rs +++ b/crates/ekore/src/harmonics.rs @@ -1,5 +1,9 @@ //! Tools to compute harmonic sums and related special functions. pub mod cache; +pub mod g_functions; pub mod polygamma; -mod w1; +pub mod w1; +pub mod w2; +pub mod w3; +pub mod w4; diff --git a/crates/ekore/src/harmonics/cache.rs b/crates/ekore/src/harmonics/cache.rs index 6ad72171d..1342f5175 100644 --- a/crates/ekore/src/harmonics/cache.rs +++ b/crates/ekore/src/harmonics/cache.rs @@ -1,16 +1,35 @@ //! Cache harmonic sums for given Mellin N. use hashbrown::HashMap; -use num::complex::Complex; +use num::{complex::Complex, Zero}; -use crate::harmonics::w1; +use crate::harmonics::{g_functions, w1, w2, w3, w4}; -#[cfg_attr(doc, katexit::katexit)] /// List of available elements. #[derive(Debug, PartialEq, Eq, Hash)] pub enum K { /// $S_1(N)$ S1, + /// $S_2(N)$ + S2, + /// $S_3(N)$ + S3, + /// $S_4(N)$ + S4, + /// $S_1(N/2)$ + S1h, + /// $S_2(N/2)$ + S2h, + /// $S_3(N/2)$ + S3h, + /// $S_1((N-1)/2)$ + S1mh, + /// $S_2((N-1)/2)$ + S2mh, + /// $S_3((N-1)/2)$ + S3mh, + /// $g_3(N)$ + G3, } /// Hold all cached values. @@ -34,15 +53,68 @@ impl Cache { pub fn get(&mut self, k: K) -> Complex { let val = self.m.get(&k); // already there? - if val.is_some() { - return *val.unwrap(); + if let Some(value) = val { + return *value; } // compute new let val = match k { K::S1 => w1::S1(self.n), + K::S2 => w2::S2(self.n), + K::S3 => w3::S3(self.n), + K::S4 => w4::S4(self.n), + K::S1h => w1::S1(self.n / 2.), + K::S2h => w2::S2(self.n / 2.), + K::S3h => w3::S3(self.n / 2.), + K::S1mh => w1::S1((self.n - 1.) / 2.), + K::S2mh => w2::S2((self.n - 1.) / 2.), + K::S3mh => w3::S3((self.n - 1.) / 2.), + K::G3 => g_functions::g3(self.n, self.get(K::S1)), }; // insert self.m.insert(k, val); val } } + +/// Recursive computation of harmonic sums. +/// +/// Compute the harmonic sum $S_{w}(N+k)$ stating from the value $S_{w}(N)$ via the recurrence relations. +pub fn recursive_harmonic_sum( + base_value: Complex, + n: Complex, + iterations: usize, + weight: u32, +) -> Complex { + let mut fact = Complex::zero(); + for i in 1..iterations + 1 { + fact += (1.0 / (n + (i as f64))).powu(weight); + } + base_value + fact +} + +#[cfg(test)] +mod tests { + use crate::harmonics::cache::recursive_harmonic_sum; + use crate::harmonics::{w1, w2, w3, w4}; + use crate::{assert_approx_eq_cmplx, cmplx}; + use num::complex::Complex; + + #[test] + fn test_recursive_harmonic_sum() { + const SX: [fn(Complex) -> Complex; 4] = [w1::S1, w2::S2, w3::S3, w4::S4]; + const NS: [Complex; 2] = [cmplx![1.0, 0.0], cmplx![2.34, 3.45]]; + const ITERS: [usize; 2] = [1, 2]; + for sit in SX.iter().enumerate() { + for nit in NS.iter().enumerate() { + let n = *nit.1; + for iit in ITERS.iter().enumerate() { + let iterations = *iit.1; + let s_base = sit.1(n); + let s_test = sit.1(n + (iterations as f64)); + let s_ref = recursive_harmonic_sum(s_base, n, iterations, 1 + (sit.0 as u32)); + assert_approx_eq_cmplx!(f64, s_test, s_ref); + } + } + } + } +} diff --git a/crates/ekore/src/harmonics/g_functions.rs b/crates/ekore/src/harmonics/g_functions.rs new file mode 100644 index 000000000..cfde9e9ea --- /dev/null +++ b/crates/ekore/src/harmonics/g_functions.rs @@ -0,0 +1,50 @@ +//! Auxilary functions for harmonics sums of weight = 3,4. + +use crate::constants::ZETA2; +use crate::harmonics::cache::recursive_harmonic_sum as s; +use num::{complex::Complex, Zero}; + +/// Compute the Mellin transform of $\text{Li}_2(x)/(1+x)$. +/// +/// This function appears in the analytic continuation of the harmonic sum +/// $S_{-2,1}(N)$ which in turn appears in the NLO anomalous dimension. +/// +/// We use the name from [\[MuselliPhD\]](crate::bib::MuselliPhD), but not his implementation - rather we use the +/// Pegasus [\[Vogt:2004ns\]](crate::bib::Vogt2004ns) implementation. +pub fn g3(N: Complex, S1: Complex) -> Complex { + const CS: [f64; 7] = [ + 1.0000e0, -0.9992e0, 0.9851e0, -0.9005e0, 0.6621e0, -0.3174e0, 0.0699e0, + ]; + let mut g3 = Complex::zero(); + for cit in CS.iter().enumerate() { + let Nj = N + (cit.0 as f64); + g3 += (*cit.1) * (ZETA2 - s(S1, N, cit.0, 1) / Nj) / Nj; + } + g3 +} + +#[cfg(test)] +mod tests { + use crate::harmonics::g_functions::g3; + use crate::harmonics::w1; + use crate::{assert_approx_eq_cmplx, cmplx}; + use num::complex::Complex; + + #[test] + fn test_mellin_g3() { + const NS: [Complex; 3] = [cmplx![1.0, 0.0], cmplx![2.0, 0.0], cmplx![1.0, 1.0]]; + // NIntegrate[x^({1, 2, 1 + I} - 1) PolyLog[2, x]/(1 + x), {x, 0, 1}] + const REFVALS: [Complex; 3] = [ + cmplx![0.3888958462, 0.], + cmplx![0.2560382207, 0.], + cmplx![0.3049381491, -0.1589060625], + ]; + for it in NS.iter().enumerate() { + let n = *it.1; + let s1 = w1::S1(n); + let refval = REFVALS[it.0]; + let g3 = g3(n, s1); + assert_approx_eq_cmplx![f64, g3, refval, epsilon = 1e-6]; + } + } +} diff --git a/crates/ekore/src/harmonics/polygamma.rs b/crates/ekore/src/harmonics/polygamma.rs index efbdae147..7415db88e 100644 --- a/crates/ekore/src/harmonics/polygamma.rs +++ b/crates/ekore/src/harmonics/polygamma.rs @@ -3,10 +3,11 @@ use num::{complex::Complex, Zero}; use std::f64::consts::PI; -#[cfg_attr(doc, katexit::katexit)] +#[allow(clippy::excessive_precision, clippy::assign_op_pattern)] /// Compute the polygamma functions $\psi_k(z)$. /// -/// Reimplementation of ``WPSIPG`` (C317) in [CERNlib](http://cernlib.web.cern.ch/cernlib/) given by [[KOLBIG1972221]][crate::bib::KOLBIG1972221]. +/// Reimplementation of ``WPSIPG`` (C317) in [CERNlib](http://cernlib.web.cern.ch/cernlib/) +/// given by [\[KOLBIG1972221\]](crate::bib::KOLBIG1972221). /// /// TODO: introduce back errors pub fn cern_polygamma(Z: Complex, K: usize) -> Complex { @@ -83,9 +84,7 @@ pub fn cern_polygamma(Z: Complex, K: usize) -> Complex { } let mut R = 1. / V.powu(2); let mut P = R * C[K][6 - 1]; - for i in (1..=5).rev() - // (int i = 5; i>1-1; i--) - { + for i in (1..=5).rev() { P = R * (C[K][i - 1] + P); } H = (SGN[K] as f64) @@ -121,9 +120,8 @@ pub fn cern_polygamma(Z: Complex, K: usize) -> Complex { #[cfg(test)] mod tests { - use crate::cmplx; use crate::harmonics::polygamma::cern_polygamma; - use float_cmp::assert_approx_eq; + use crate::{assert_approx_eq_cmplx, cmplx}; use num::complex::Complex; #[test] @@ -202,8 +200,7 @@ mod tests { for zit in ZS.iter().enumerate() { let fref = FORTRAN_REF[kit.0][zit.0]; let me = cern_polygamma(*zit.1, *kit.1); - assert_approx_eq!(f64, me.re, fref.re, ulps = 32); - assert_approx_eq!(f64, me.im, fref.im, ulps = 32); + assert_approx_eq_cmplx!(f64, me, fref, ulps = 32); } } } diff --git a/crates/ekore/src/harmonics/w1.rs b/crates/ekore/src/harmonics/w1.rs index 2b861cb30..a1aa893d9 100644 --- a/crates/ekore/src/harmonics/w1.rs +++ b/crates/ekore/src/harmonics/w1.rs @@ -1,3 +1,4 @@ +//! Harmonic sums of weight 1. use num::complex::Complex; use crate::harmonics::polygamma::cern_polygamma; @@ -7,5 +8,5 @@ use crate::harmonics::polygamma::cern_polygamma; /// $$S_1(N) = \sum\limits_{j=1}^N \frac 1 j = \psi_0(N+1)+\gamma_E$$ /// with $\psi_0(N)$ the digamma function and $\gamma_E$ the Euler-Mascheroni constant. pub fn S1(N: Complex) -> Complex { - cern_polygamma(N + 1.0, 0) + 0.5772156649015328606065120 + cern_polygamma(N + 1.0, 0) + 0.577_215_664_901_532_9 } diff --git a/crates/ekore/src/harmonics/w2.rs b/crates/ekore/src/harmonics/w2.rs new file mode 100644 index 000000000..d55a32679 --- /dev/null +++ b/crates/ekore/src/harmonics/w2.rs @@ -0,0 +1,13 @@ +//! Harmonic sums of weight 2. +use num::complex::Complex; + +use crate::constants::ZETA2; +use crate::harmonics::polygamma::cern_polygamma; + +/// Compute the harmonic sum $S_2(N)$. +/// +/// $$S_2(N) = \sum\limits_{j=1}^N \frac 1 {j^2} = -\psi_1(N+1)+\zeta(2)$$ +/// with $\psi_1(N)$ the trigamma function and $\zeta$ the Riemann zeta function. +pub fn S2(N: Complex) -> Complex { + -cern_polygamma(N + 1.0, 1) + ZETA2 +} diff --git a/crates/ekore/src/harmonics/w3.rs b/crates/ekore/src/harmonics/w3.rs new file mode 100644 index 000000000..7850c678d --- /dev/null +++ b/crates/ekore/src/harmonics/w3.rs @@ -0,0 +1,13 @@ +//! Harmonic sums of weight 3. +use num::complex::Complex; + +use crate::constants::ZETA3; +use crate::harmonics::polygamma::cern_polygamma; + +/// Compute the harmonic sum $S_3(N)$. +/// +/// $$S_3(N) = \sum\limits_{j=1}^N \frac 1 {j^3} = \frac 1 2 \psi_2(N+1)+\zeta(3)$$ +/// with $\psi_2(N)$ the 2nd polygamma function and $\zeta$ the Riemann zeta function. +pub fn S3(N: Complex) -> Complex { + 0.5 * cern_polygamma(N + 1.0, 2) + ZETA3 +} diff --git a/crates/ekore/src/harmonics/w4.rs b/crates/ekore/src/harmonics/w4.rs new file mode 100644 index 000000000..66835ac5f --- /dev/null +++ b/crates/ekore/src/harmonics/w4.rs @@ -0,0 +1,13 @@ +//! Harmonic sums of weight 4. +use num::complex::Complex; + +use crate::constants::ZETA4; +use crate::harmonics::polygamma::cern_polygamma; + +/// Compute the harmonic sum $S_4(N)$. +/// +/// $$S_4(N) = \sum\limits_{j=1}^N \frac 1 {j^4} = - \frac 1 6 \psi_3(N+1)+\zeta(4)$$ +/// with $\psi_3(N)$ the 3rd polygamma function and $\zeta$ the Riemann zeta function. +pub fn S4(N: Complex) -> Complex { + ZETA4 - 1.0 / 6.0 * cern_polygamma(N + 1.0, 3) +} diff --git a/crates/ekore/src/util.rs b/crates/ekore/src/util.rs index 5c4e34f4d..55b1ab2bd 100644 --- a/crates/ekore/src/util.rs +++ b/crates/ekore/src/util.rs @@ -7,3 +7,23 @@ macro_rules! cmplx { Complex::new($re, $im) }; } + +/// Shorthand complex number contructor. +#[macro_export] +macro_rules! assert_approx_eq_cmplx { + ($size:ty, $ref:expr, $target:expr) => { + use float_cmp::assert_approx_eq; + assert_approx_eq!($size, $ref.re, $target.re); + assert_approx_eq!($size, $ref.im, $target.im); + }; + ($size:ty, $ref:expr, $target:expr, ulps=$ulps:expr) => { + use float_cmp::assert_approx_eq; + assert_approx_eq!($size, $ref.re, $target.re, ulps = $ulps); + assert_approx_eq!($size, $ref.im, $target.im, ulps = $ulps); + }; + ($size:ty, $ref:expr, $target:expr, epsilon=$epsilon:expr) => { + use float_cmp::assert_approx_eq; + assert_approx_eq!($size, $ref.re, $target.re, epsilon = $epsilon); + assert_approx_eq!($size, $ref.im, $target.im, epsilon = $epsilon); + }; +} diff --git a/crates/make_bib.py b/crates/make_bib.py index 1b15d663d..e758c41ad 100644 --- a/crates/make_bib.py +++ b/crates/make_bib.py @@ -1,4 +1,5 @@ """Parse bibtex file to rust crate.""" + import datetime import pathlib import re @@ -9,7 +10,8 @@ BIBFILE = pathlib.Path(__file__).parent / "ekore" / "refs.bib" # A single entry -ENTRY = """/// {title} +ENTRY = """#[allow(non_snake_case)] +/// {title} /// /// {author} /// @@ -20,6 +22,7 @@ /// {doi}""" # Combine publication information PUB = """Published in: {journal} {volume} ({year}), {pages}""" +PHD = """Published as PhD thesis at {school} ({year})""" def clean_nl(t: str) -> str: @@ -38,12 +41,18 @@ def clean_nl(t: str) -> str: for el in bib_database.entries: title = re.sub(r"^\{(.+)\}$", r"\1", clean_nl(el.fields_dict["title"].value)) author = el.fields_dict["author"].value - publication = PUB.format( - journal=el.fields_dict["journal"].value, - volume=el.fields_dict["volume"].value, - year=el.fields_dict["year"].value, - pages=el.fields_dict["pages"].value, - ) + if el.entry_type == "phdthesis": + publication = PHD.format( + school=el.fields_dict["school"].value, + year=el.fields_dict["year"].value, + ) + else: + publication = PUB.format( + journal=el.fields_dict["journal"].value, + volume=el.fields_dict["volume"].value, + year=el.fields_dict["year"].value, + pages=el.fields_dict["pages"].value, + ) eprint = "" if ( "eprint" in el.fields_dict diff --git a/crates/parse-abbrev.py b/crates/parse-abbrev.py new file mode 100644 index 000000000..b928ed03c --- /dev/null +++ b/crates/parse-abbrev.py @@ -0,0 +1,20 @@ +"""Parse abbreviations from sphinx to Rust.""" + +import pathlib +import re + +SRC = ( + pathlib.Path(__file__).parents[1] + / "doc" + / "source" + / "shared" + / "abbreviations.rst" +) + +cnt = SRC.read_text("utf-8") +for el in cnt.split(".."): + test = re.match(r"\s*(.+)\s+replace::\n\s+:abbr:`(.+?)\((.+)\)`", el.strip()) + if test is None: + continue + # Print to terminal - the user can dump to the relevant file + print(f'"{test[2].strip()}": "{test[3].strip()}",') diff --git a/crates/release.json b/crates/release.json new file mode 100644 index 000000000..c2b9f6f54 --- /dev/null +++ b/crates/release.json @@ -0,0 +1 @@ +["ekore", "eko"] diff --git a/doc/source/code/genpdf.rst b/doc/source/code/genpdf.rst index f9d52bd47..ab3f94673 100644 --- a/doc/source/code/genpdf.rst +++ b/doc/source/code/genpdf.rst @@ -3,40 +3,46 @@ genpdf We provide also a console script called ``genpdf`` that is able to generate and install a custom |PDF| set in the `lhapdf` format. -In particular, the command ``genpdf install [NAME]`` simply -install the |PDF| called ``[NAME]`` in the lhapdf folder and -the ``genpdf generate [NAME]`` command generates the custom |PDF| + +To use it, you have to install the additional `ekobox` dependencies via +the pip extra `box`: + +.. code-block:: bash + + $ pip install eko[box] + +The ``genpdf generate [NAME]`` command generates a custom |PDF| and saves it as ``[NAME]`` in the current directory. -Notice that the argument ``[NAME]`` is the only mandatory one. +Afterwards, it can be conveniently installed using the ``genpdf install [NAME]`` command +(which simply copies the generated folder into the LHAPDF folder). +Note that the argument ``[NAME]`` is the only mandatory one. -The custom |PDF| can be generated in three different ways which -are accessible trough the option ``-p [PARENT]`` (the complete spelling -is ``genpdf generate [NAME] -p [PARENT]``): +A custom |PDF| can be generated in three different ways which +are accessible trough the option ``-p [PARENT]``: 1. If ``[PARENT]`` is the name of an available |PDF|, it is used as parent - |PDF| and thus copied to generate the new custom PDF. - 2. If ``[PARENT]`` is "toylh" or "toy", the **toy** |PDF| is used as parent. + |PDF| and thus copied to generate the new custom PDF. + 2. If ``[PARENT]`` is "toylh" or "toy", the **toy** |PDF| :cite:`Giele:2002hx,Dittmar:2005ed` is used as parent. 3. If the option ``-p [PARENT]`` is not used, the |PDF| is - generated using **x(1-x)** for all the flavors. + generated using **x(1-x)** for all the flavors. -Trough the use of the argument -``[LABEL]`` (``genpdf generate [NAME] [LABEL] [OPTIONS]``) it is also possible +Through the use of the argument +``[LABEL]`` (``genpdf generate [NAME] [LABEL] [OPTIONS]``) it is possible to specify a set of flavors (expressed in |pid| basis) or a set of -**evolution basis components** on which filtering the custom |PDF|. -In this way the specified set is kept in the final |PDF|, while the rest -is discarded. +evolution basis components on which to filter the new |PDF|. +In this way the specified set is kept in the new |PDF|, while the rest +is discarded, i.e. set to zero. In the case of custom |PDF| generated starting from a parent |PDF|, it is possible to generate all the members trough the flag ``-m``. If this flag is not used, only the *zero* member is generated (together with the *info* -file of course). Using the flag ``-m`` when the custom |PDF| is generated -either using the **toy** |PDF| or the **x(1-x)** function, has no effects. +file of course). Using the flag ``-m`` when a custom |PDF| is generated +either using the **toy** |PDF| or the **x(1-x)** function has no effects. In order to automatically install the custom |PDF| in the lhapdf folder at generation time (so without using ``genpdf install [NAME]`` after the generation), it is possible to use the ``-i`` flag. - We also provide an API with some additional features and possibilities such as generating a |PDF| with a custom function for every |pid| (through a ``dict`` structure) and filtering custom combination of @@ -49,7 +55,7 @@ Examples $ genpdf generate gonly 21 -This will generate the custom PDF using the debug x(1-x) PDF as parent +This will generate a custom PDF using the debug x(1-x) PDF as parent and then it will keep only the gluon. .. code-block:: bash @@ -62,7 +68,7 @@ This will install the previous PDF in the lhapdf folder. $ genpdf generate Sonly S -p toy -i -This will generate the custom PDF using the toy PDF as parent and then +This will generate a custom PDF using the toy PDF as parent and then it will keep only the singlet combination. The generated PDF is also automatically installed in the lhapdf folder. @@ -70,6 +76,14 @@ automatically installed in the lhapdf folder. $ genpdf generate Vonly V -p CT10 -m -This will generate the custom PDF using the CT10 PDF set as parent +This will generate a custom PDF using the CT10 PDF set as parent (if available) and it will keep only the valence combination. Moreover it will generate all the members of the parent PDF. + +.. code-block:: bash + + $ genpdf generate NN40qqbar -p NNPDF40_nnlo_as_01180 -- -5 -4 -3 -2 -1 1 2 3 4 5 + +This will generate a custom PDF with no gluon contributions, but all quarks +taken are from NNPDF4.0. Note that (as customary with CLIs) you have to add the explicit +separator ``--`` before specifying anti-quark flavors. diff --git a/doc/source/conf.py b/doc/source/conf.py index c271bd870..1f03599ac 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -27,7 +27,7 @@ # -- Project information ----------------------------------------------------- project = "EKO" -copyright = "2019-2023, the NNPDF team" # pylint: disable=redefined-builtin +copyright = "2019-2024, the NNPDF team" # pylint: disable=redefined-builtin author = "NNPDF team" # The short X.Y version @@ -112,10 +112,10 @@ ) extlinks = { - "yadism": ("https://n3pdf.github.io/yadism/%s", "yadism"), - "banana": ("https://n3pdf.github.io/banana/%s", "banana"), - "pineappl": ("https://n3pdf.github.io/pineappl/%s", "pineappl"), - "pineko": ("https://github.com/N3PDF/pineko/%s", "pineko"), + "yadism": ("https://n3pdf.github.io/yadism/%s", "yadism%s"), + "banana": ("https://n3pdf.github.io/banana/%s", "banana%s"), + "pineappl": ("https://n3pdf.github.io/pineappl/%s", "pineappl%s"), + "pineko": ("https://github.com/N3PDF/pineko/%s", "pineko%s"), } # -- Options for HTML output ------------------------------------------------- diff --git a/doc/source/overview/tutorials/alpha_s.ipynb b/doc/source/overview/tutorials/alpha_s.ipynb index a9d75c0ca..f9cc5a240 100644 --- a/doc/source/overview/tutorials/alpha_s.ipynb +++ b/doc/source/overview/tutorials/alpha_s.ipynb @@ -39,12 +39,10 @@ "from eko.quantities.heavy_quarks import MatchingScales, QuarkMassScheme\n", "\n", "# set the (alpha_s, alpha_em) reference values\n", - "couplings_ref = CouplingsInfo(\n", - " alphas=0.118, alphaem=0.007496252, scale=91.0, num_flavs_ref=None, max_num_flavs=5\n", - ")\n", + "couplings_ref = CouplingsInfo(alphas=0.118, alphaem=0.007496252, ref=(91.0, 5))\n", "\n", "# set heavy quark masses and their threshold ratios\n", - "heavy_quark_masses = np.power([1.51, 4.92, 172.0],2)\n", + "heavy_quark_masses = np.power([1.51, 4.92, 172.0], 2)\n", "thresholds_ratios = np.array([1.0, 1.0, 1.0])\n", "\n", "# set (QCD,QED) perturbative order\n", @@ -88,9 +86,9 @@ } ], "source": [ - "target_scale = 10.0 ** 2\n", + "target_scale = 10.0**2\n", "a_s = sc.a_s(target_scale)\n", - "print(\"The value of alpha_s at Q^2=100 GeV^2 is: \", 4. * np.pi * a_s)" + "print(\"The value of alpha_s at Q^2=100 GeV^2 is: \", 4.0 * np.pi * a_s)" ] }, { @@ -105,13 +103,10 @@ } ], "metadata": { - "interpreter": { - "hash": "0a84ba3ac8703c04e87bc503a7d00188dfd591ad56130da93c406115a1e4a408" - }, "kernelspec": { - "display_name": "eko-KkPVjVhh-py3.10", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "eko-kkpvjvhh-py3.10" + "name": "python3" }, "language_info": { "codemirror_mode": { diff --git a/doc/source/overview/tutorials/dglap.ipynb b/doc/source/overview/tutorials/dglap.ipynb index 0e271a00c..98cb4a6e1 100644 --- a/doc/source/overview/tutorials/dglap.ipynb +++ b/doc/source/overview/tutorials/dglap.ipynb @@ -68,7 +68,7 @@ "th_card = example.theory()\n", "op_card = example.operator()\n", "# here we replace the grid with a very minimal one, to speed up the example\n", - "op_card.xgrid = [1e-3, 1e-2, 1e-1, 5e-1, 1.]" + "op_card.xgrid = [1e-3, 1e-2, 1e-1, 5e-1, 1.0]" ] }, { @@ -91,14 +91,9 @@ "{'order': [1, 0],\n", " 'couplings': {'alphas': 0.118,\n", " 'alphaem': 0.007496252,\n", - " 'scale': 91.2,\n", - " 'max_num_flavs': 6,\n", - " 'num_flavs_ref': 5,\n", + " 'ref': [91.2, 5],\n", " 'em_running': False},\n", - " 'heavy': {'num_flavs_init': 4,\n", - " 'num_flavs_max_pdf': 6,\n", - " 'intrinsic_flavors': [4],\n", - " 'masses': [[2.0, nan], [4.5, nan], [173.07, nan]],\n", + " 'heavy': {'masses': [[2.0, nan], [4.5, nan], [173.07, nan]],\n", " 'masses_scheme': 'pole',\n", " 'matching_ratios': [1.0, 1.0, 1.0]},\n", " 'xif': 1.0,\n", @@ -123,7 +118,7 @@ { "data": { "text/plain": [ - "{'mu0': 1.65,\n", + "{'init': [1.65, 4],\n", " 'mugrid': [[100.0, 5]],\n", " 'xgrid': [0.001, 0.01, 0.1, 0.5, 1.0],\n", " 'configs': {'evolution_method': 'iterate-exact',\n", @@ -174,7 +169,7 @@ "id": "880aadcf-8f87-4918-a0bc-09581d0d3579", "metadata": {}, "source": [ - "The actual result is a complicate EKO object, we will discuss it in a separate tutorial.\n", + "The actual result is a complicate EKO object, which we will discuss it in a separate tutorial.\n", "\n", "You have just run your first DGLAP calculation!" ] diff --git a/doc/source/overview/tutorials/output.ipynb b/doc/source/overview/tutorials/output.ipynb index 47345ac35..1cfe9f071 100644 --- a/doc/source/overview/tutorials/output.ipynb +++ b/doc/source/overview/tutorials/output.ipynb @@ -34,7 +34,7 @@ "id": "2f8f0666-c6ab-40f6-86f5-15773f205b51", "metadata": {}, "source": [ - "We can access the operator, by using the `open` method (similar to python's `open`):" + "We can access the operator, by using the `read` method:" ] }, { @@ -76,8 +76,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "TheoryCard(order=(1, 0), couplings=CouplingsInfo(alphas=0.118, alphaem=0.007496252, scale=91.2, max_num_flavs=6, num_flavs_ref=5, em_running=False), heavy=HeavyInfo(num_flavs_init=4, num_flavs_max_pdf=6, intrinsic_flavors=[4, 5, 6], masses=[[2.0, nan], [4.5, nan], [173.07, nan]], masses_scheme=, matching_ratios=[1.0, 1.0, 1.0]), xif=1.0, n3lo_ad_variation=(0, 0, 0, 0))\n", - "OperatorCard(mu0=1.65, mugrid=[(100.0, 5)], xgrid=, configs=Configs(evolution_method=, ev_op_max_order=(10, 0), ev_op_iterations=10, scvar_method=None, inversion_method=None, interpolation_polynomial_degree=4, interpolation_is_log=True, polarized=False, time_like=False, n_integration_cores=0), debug=Debug(skip_singlet=False, skip_non_singlet=False), eko_version='0.0.0')\n" + "TheoryCard(order=(1, 0), couplings=CouplingsInfo(alphas=0.118, alphaem=0.007496252, ref=(91.2, 5), em_running=False), heavy=HeavyInfo(masses=[[2.0, nan], [4.5, nan], [173.07, nan]], masses_scheme=, matching_ratios=[1.0, 1.0, 1.0]), xif=1.0, n3lo_ad_variation=(0, 0, 0, 0))\n", + "OperatorCard(init=(1.65, 4), mugrid=[(100.0, 5)], xgrid=, configs=Configs(evolution_method=, ev_op_max_order=(10, 0), ev_op_iterations=10, scvar_method=None, inversion_method=None, interpolation_polynomial_degree=4, interpolation_is_log=True, polarized=False, time_like=False, n_integration_cores=0), debug=Debug(skip_singlet=False, skip_non_singlet=False), eko_version='0.0.0')\n" ] } ], @@ -143,7 +143,7 @@ ], "source": [ "with eko.EKO.read(\"./myeko.tar\") as evolution_operator:\n", - " with evolution_operator.operator((10000.,5)) as op:\n", + " with evolution_operator.operator((10000.0, 5)) as op:\n", " print(f\"operator: {op.operator.shape}\")\n", " print(f\"error: {op.error.shape}\")" ] diff --git a/doc/source/overview/tutorials/pdf.ipynb b/doc/source/overview/tutorials/pdf.ipynb index 4607ef891..bfc6ad3ad 100644 --- a/doc/source/overview/tutorials/pdf.ipynb +++ b/doc/source/overview/tutorials/pdf.ipynb @@ -13,9 +13,9 @@ "id": "3e0dcd0f", "metadata": {}, "source": [ - "## Method 1: Using apply_pdf\n", + "## Method 1: Using `apply_pdf`\n", "\n", - "In this first part we will compute the eko and subsequently apply the initial PDF \"manually\" calling a dedicated function. " + "In this first part, we compute the eko and subsequently apply the initial PDF \"manually\" calling a dedicated function. " ] }, { @@ -52,6 +52,7 @@ "import pathlib\n", "import eko\n", "from banana import toy\n", + "\n", "pdf = toy.mkPDF(\"\", 0)" ] }, @@ -71,6 +72,7 @@ "outputs": [], "source": [ "from ekobox.apply import apply_pdf\n", + "\n", "with eko.EKO.read(\"./myeko.tar\") as evolution_operator:\n", " evolved_pdfs = apply_pdf(evolution_operator, pdf)" ] @@ -92,7 +94,7 @@ { "data": { "text/plain": [ - "dict_keys([10000.0])" + "dict_keys([(10000.0, 5)])" ] }, "execution_count": 3, @@ -134,7 +136,7 @@ } ], "source": [ - "evolved_pdfs[10000.0][\"pdfs\"][21]" + "evolved_pdfs[(10000.0, 5)][\"pdfs\"][21]" ] }, { @@ -150,7 +152,7 @@ "id": "e925d2c9", "metadata": {}, "source": [ - "## Method 2: Using evolve_pdfs\n", + "## Method 2: Using `evolve_pdfs`\n", "\n", "In this second part we illustrate how to get (and install) directly a LHAPDF set evolved with eko. " ] @@ -171,6 +173,7 @@ "outputs": [], "source": [ "from banana import toy\n", + "\n", "pdf = toy.mkPDF(\"\", 0)" ] }, @@ -195,10 +198,10 @@ "th_card = example.theory()\n", "op_card = example.operator()\n", "# here we replace the grid with a very minimal one, to speed up the example\n", - "op_card.xgrid = eko.interpolation.XGrid([1e-3, 1e-2, 1e-1, 5e-1, 1.])\n", - "op_card.mugrid = [(10.,5), (100.,5)]\n", + "op_card.xgrid = eko.interpolation.XGrid([1e-3, 1e-2, 1e-1, 5e-1, 1.0])\n", + "op_card.mugrid = [(10.0, 5), (100.0, 5)]\n", "# set QCD LO evolution\n", - "th_card.orders = (1,0)" + "th_card.orders = (1, 0)" ] }, { @@ -236,16 +239,10 @@ ], "source": [ "from ekobox.evol_pdf import evolve_pdfs\n", + "\n", "path = pathlib.Path(\"./myeko2.tar\")\n", "path.unlink(missing_ok=True)\n", - "evolve_pdfs(\n", - " [pdf],\n", - " th_card,\n", - " op_card,\n", - " install=True,\n", - " name=\"Evolved_PDF\",\n", - " store_path=path\n", - ")" + "evolve_pdfs([pdf], th_card, op_card, install=True, name=\"Evolved_PDF\", store_path=path)" ] }, { @@ -273,6 +270,7 @@ ], "source": [ "import lhapdf\n", + "\n", "evolved_pdf = lhapdf.mkPDF(\"Evolved_PDF\", 0)" ] }, @@ -300,12 +298,12 @@ } ], "source": [ - "pid = 21 # gluon pid\n", - "Q2 = 89.10 # Q^2 in Gev^2\n", - "x = 0.01 # momentum fraction \n", + "pid = 21 # gluon pid\n", + "Q2 = 89.10 # Q^2 in Gev^2\n", + "x = 0.01 # momentum fraction\n", "\n", "# check that the particle is present\n", - "print(\"has gluon?\",evolved_pdf.hasFlavor(pid))\n", + "print(\"has gluon?\", evolved_pdf.hasFlavor(pid))\n", "# now do the lookup\n", "xg = evolved_pdf.xfxQ2(pid, x, Q2)\n", "print(f\"xg(x={x}, Q2={Q2}) = {xg}\")" @@ -352,28 +350,28 @@ "import lhapdf\n", "from ekobox.cards import example\n", "from eko.interpolation import make_grid\n", - "from eko.quantities.heavy_quarks import QuarkMassRef,HeavyQuarks\n", + "from eko.quantities.heavy_quarks import QuarkMassRef, HeavyQuarks\n", "\n", "# get the PDF object\n", "ct14llo = lhapdf.mkPDF(\"CT14llo\")\n", "\n", "# setup the operator card\n", "op_card = example.operator()\n", - "op_card.xgrid = eko.interpolation.XGrid(make_grid(30, 30)) # x grid\n", - "op_card.mugrid = [(float(q),5) for q in np.geomspace(5., 100, 5)] # Q2 grid\n", - "op_card.mu0 = 1.295000 # starting point for the evolution \n", + "op_card.xgrid = eko.interpolation.XGrid(make_grid(30, 30)) # x grid\n", + "op_card.mugrid = [(float(q), 5) for q in np.geomspace(5.0, 100, 5)] # Q2 grid\n", + "op_card.init = (1.295000, 3) # starting point for the evolution\n", "\n", "# setup the theory card - this can be mostly inferred from the PDF's .info file\n", - "\n", "th_card = example.theory()\n", - "th_card.orders = (1,0) # QCD LO\n", - "th_card.heavy.masses = HeavyQuarks([QuarkMassRef([1.3,nan]), QuarkMassRef([4.75,nan]), QuarkMassRef([172.,nan])]) # quark mass\n", - "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", - "th_card.couplings.scale = 91.1876 # the reference scale at which alpha_s is provided\n", - "th_card.couplings.num_flavs_ref = 5 # the number of flavors active at the alpha_s reference scale\n", - "th_card.couplings.max_num_flavs = 5 # the maximum number of flavors active in the alpha_s evolution\n", - "th_card.couplings.num_flavs_init = 3 # the number of flavors active at the reference scale\n", - "th_card.num_flavs_max_pdf = 5 # the maximum number of flavors active in the pdf evolution." + "th_card.orders = (1, 0) # QCD LO\n", + "th_card.heavy.masses = HeavyQuarks(\n", + " [QuarkMassRef([1.3, nan]), QuarkMassRef([4.75, nan]), QuarkMassRef([172.0, nan])]\n", + ") # quark mass\n", + "th_card.couplings.alphas = 0.130000 # reference value of alpha_s\n", + "th_card.couplings.ref = (\n", + " 91.1876,\n", + " 5,\n", + ") # the reference scale together with the number of flavors at which alpha_s is provided" ] }, { @@ -407,15 +405,11 @@ ], "source": [ "from ekobox.evol_pdf import evolve_pdfs\n", + "\n", "path = pathlib.Path(\"./myeko_ct14llo.tar\")\n", "path.unlink(missing_ok=True)\n", "evolve_pdfs(\n", - " [ct14llo],\n", - " th_card,\n", - " op_card,\n", - " install=True,\n", - " name=\"my_ct14llo\",\n", - " store_path=path\n", + " [ct14llo], th_card, op_card, install=True, name=\"my_ct14llo\", store_path=path\n", ")" ] }, @@ -439,33 +433,33 @@ "output_type": "stream", "text": [ "LHAPDF 6.4.0 loading /home/felix/local/share/LHAPDF/my_ct14llo/my_ct14llo_0000.dat\n", + "my_ct14llo PDF set, member #0, version 1\n", " x Q2 ct14llo my_ct14llo relative_diff\n", - "0 0.000010 25.000000 7.635785e+01 7.630461e+01 0.000697\n", - "1 0.000173 25.000000 3.194273e+01 3.192092e+01 0.000683\n", - "2 0.003000 25.000000 1.081843e+01 1.081086e+01 0.000701\n", - "3 0.051962 25.000000 1.958956e+00 1.958632e+00 0.000166\n", - "4 0.900000 25.000000 1.922415e-05 1.955026e-05 -0.016963\n", - "5 0.000010 111.803399 1.333957e+02 1.332985e+02 0.000729\n", - "6 0.000173 111.803399 4.777286e+01 4.773664e+01 0.000758\n", - "7 0.003000 111.803399 1.341028e+01 1.339967e+01 0.000791\n", - "8 0.051962 111.803399 1.978216e+00 1.978130e+00 0.000044\n", - "9 0.900000 111.803399 6.644805e-06 6.753652e-06 -0.016381\n", - "10 0.000010 500.000000 1.967032e+02 1.965456e+02 0.000801\n", - "11 0.000173 500.000000 6.291393e+01 6.286095e+01 0.000842\n", - "12 0.003000 500.000000 1.542347e+01 1.540996e+01 0.000876\n", - "13 0.051962 500.000000 1.947465e+00 1.947391e+00 0.000038\n", - "14 0.900000 500.000000 2.929060e-06 2.977306e-06 -0.016471\n", - "15 0.000010 2236.067977 2.633266e+02 2.631109e+02 0.000819\n", - "16 0.000173 2236.067977 7.708540e+01 7.701938e+01 0.000856\n", - "17 0.003000 2236.067977 1.700410e+01 1.698928e+01 0.000872\n", - "18 0.051962 2236.067977 1.893923e+00 1.893971e+00 -0.000025\n", - "19 0.900000 2236.067977 1.544450e-06 1.570997e-06 -0.017189\n", - "20 0.000010 10000.000000 3.314097e+02 3.311351e+02 0.000829\n", - "21 0.000173 10000.000000 9.023010e+01 9.015279e+01 0.000857\n", - "22 0.003000 10000.000000 1.825934e+01 1.824402e+01 0.000839\n", - "23 0.051962 10000.000000 1.830992e+00 1.831183e+00 -0.000104\n", - "24 0.900000 10000.000000 9.288458e-07 9.447927e-07 -0.017169\n", - "my_ct14llo PDF set, member #0, version 1\n" + "0 0.000010 25.000000 7.635785e+01 7.630719e+01 0.000663\n", + "1 0.000173 25.000000 3.194273e+01 3.192239e+01 0.000637\n", + "2 0.003000 25.000000 1.081843e+01 1.081160e+01 0.000632\n", + "3 0.051962 25.000000 1.958956e+00 1.958820e+00 0.000069\n", + "4 0.900000 25.000000 1.922415e-05 1.955440e-05 -0.017179\n", + "5 0.000010 111.803399 1.333957e+02 1.333028e+02 0.000697\n", + "6 0.000173 111.803399 4.777286e+01 4.773855e+01 0.000718\n", + "7 0.003000 111.803399 1.341028e+01 1.340044e+01 0.000734\n", + "8 0.051962 111.803399 1.978216e+00 1.978292e+00 -0.000038\n", + "9 0.900000 111.803399 6.644805e-06 6.756354e-06 -0.016787\n", + "10 0.000010 500.000000 1.967032e+02 1.965517e+02 0.000770\n", + "11 0.000173 500.000000 6.291393e+01 6.286327e+01 0.000805\n", + "12 0.003000 500.000000 1.542347e+01 1.541073e+01 0.000826\n", + "13 0.051962 500.000000 1.947465e+00 1.947532e+00 -0.000034\n", + "14 0.900000 500.000000 2.929060e-06 2.979511e-06 -0.017224\n", + "15 0.000010 2236.067977 2.633266e+02 2.631189e+02 0.000789\n", + "16 0.000173 2236.067977 7.708540e+01 7.702204e+01 0.000822\n", + "17 0.003000 2236.067977 1.700410e+01 1.699004e+01 0.000827\n", + "18 0.051962 2236.067977 1.893923e+00 1.894094e+00 -0.000090\n", + "19 0.900000 2236.067977 1.544450e-06 1.572860e-06 -0.018395\n", + "20 0.000010 10000.000000 3.314097e+02 3.311450e+02 0.000799\n", + "21 0.000173 10000.000000 9.023010e+01 9.015576e+01 0.000824\n", + "22 0.003000 10000.000000 1.825934e+01 1.824477e+01 0.000798\n", + "23 0.051962 10000.000000 1.830992e+00 1.831291e+00 -0.000163\n", + "24 0.900000 10000.000000 9.288458e-07 9.463689e-07 -0.018866\n" ] } ], @@ -475,15 +469,15 @@ "# load evolved pdf\n", "my_ct14llo = lhapdf.mkPDF(\"my_ct14llo\", 0)\n", "\n", - "pid = 21 # gluon pid\n", + "pid = 21 # gluon pid\n", "\n", "# collect data\n", - "log = {\"x\": [], \"Q2\" : [], \"ct14llo\": [], \"my_ct14llo\": [], \"relative_diff\": []} \n", - "for q in np.geomspace(5., 100, 5):\n", - " q2 = q**2.\n", + "log = {\"x\": [], \"Q2\": [], \"ct14llo\": [], \"my_ct14llo\": [], \"relative_diff\": []}\n", + "for q in np.geomspace(5.0, 100, 5):\n", + " q2 = q**2.0\n", " for x in np.geomspace(1e-5, 0.9, 5):\n", " value = ct14llo.xfxQ2(pid, x, q2)\n", - " my_value = my_ct14llo.xfxQ2(pid, x, q2)\n", + " my_value = my_ct14llo.xfxQ2(pid, x, q2)\n", " log[\"x\"].append(x)\n", " log[\"Q2\"].append(q2)\n", " log[\"ct14llo\"].append(value)\n", diff --git a/doc/source/refs.bib b/doc/source/refs.bib index 16a662451..769f2e326 100644 --- a/doc/source/refs.bib +++ b/doc/source/refs.bib @@ -823,14 +823,18 @@ @article{Kawamura:2012cr @article{Falcioni:2023luc, author = "Falcioni, G. and Herzog, F. and Moch, S. and Vogt, A.", - title = "{Four-loop splitting functions in QCD -- The quark-quark case}", + title = "{Four-loop splitting functions in QCD \textendash{} The quark-quark case}", eprint = "2302.07593", archivePrefix = "arXiv", primaryClass = "hep-ph", reportNumber = "DESY 23--022, LTH 1333", - month = "2", + doi = "10.1016/j.physletb.2023.137944", + journal = "Phys. Lett. B", + volume = "842", + pages = "137944", year = "2023" } + @article{Gluck:1995yr, author = "Gluck, M. and Reya, E. and Stratmann, M. and Vogelsang, W.", title = "{Next-to-leading order radiative parton model analysis of polarized deep inelastic lepton - nucleon scattering}", @@ -991,24 +995,30 @@ @article{Dokshitzer:2005bf @article{Falcioni:2023vqq, author = "Falcioni, G. and Herzog, F. and Moch, S. and Vogt, A.", - title = "{Four-loop splitting functions in QCD -- The gluon-to-quark case}", + title = "{Four-loop splitting functions in QCD \textendash{} The gluon-to-quark case}", eprint = "2307.04158", archivePrefix = "arXiv", primaryClass = "hep-ph", reportNumber = "DESY 23-096, LTH 1345", - month = "7", + doi = "10.1016/j.physletb.2023.138215", + journal = "Phys. Lett. B", + volume = "846", + pages = "138215", year = "2023" } @article{Gehrmann:2023cqm, author = "Gehrmann, Thomas and von Manteuffel, Andreas and Sotnikov, Vasily and Yang, Tong-Zhi", - title = "{Complete $N_f^2$ contributions to four-loop pure-singlet splitting functions}", + title = "{Complete $ {N}_f^2 $ contributions to four-loop pure-singlet splitting functions}", eprint = "2308.07958", archivePrefix = "arXiv", primaryClass = "hep-ph", reportNumber = "MSUHEP-23-024, ZU-TH 43/23", - month = "8", - year = "2023" + doi = "10.1007/JHEP01(2024)029", + journal = "JHEP", + volume = "01", + pages = "029", + year = "2024" } @article{Falcioni:2023tzp, @@ -1018,8 +1028,11 @@ @article{Falcioni:2023tzp archivePrefix = "arXiv", primaryClass = "hep-ph", reportNumber = "ZU-TH 62/23, DESY 23-146, Nikhef 2023-015, LTH 1353", - month = "10", - year = "2023" + doi = "10.1016/j.physletb.2023.138351", + journal = "Phys. Lett. B", + volume = "848", + pages = "138351", + year = "2024" } @article{Moch:2023tdj, @@ -1029,6 +1042,34 @@ @article{Moch:2023tdj archivePrefix = "arXiv", primaryClass = "hep-ph", reportNumber = "DESY-23-150, Nikhef 23-016, LTH 1354", - month = "10", - year = "2023" + doi = "10.1016/j.physletb.2024.138468", + journal = "Phys. Lett. B", + volume = "849", + pages = "138468", + year = "2024" +} + +@article{Ablinger:2024xtt, + author = {Ablinger, J. and Behring, A. and Bl\"umlein, J. and De Freitas, A. and von Manteuffel, A. and Schneider, C. and Sch\"onwald, K.}, + title = "{The non-first-order-factorizable contributions to the three-loop single-mass operator matrix elements $A_{Qg}^{(3)}$ and $\Delta A_{Qg}^{(3)}$}", + eprint = "2403.00513", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + reportNumber = "DO--TH 23/15. DESY 24--027, RISC Report series 24--02, ZU-TH 13/24, + CERN-TH-2024-30, DO-TH 23/15, RISC Report series 24--02, ZU-TH 13/24, + CERN-TH-2024-30, DESY-24-027", + month = "3", + year = "2024", + journal = "" +} + +@article{Falcioni:2024xyt, + author = "Falcioni, G. and Herzog, F. and Moch, S. and Pelloni, A. and Vogt, A.", + title = "{Four-loop splitting functions in QCD -- The quark-to-gluon case}", + eprint = "2404.09701", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + reportNumber = "ZU-TH 20/24, DESY-24-053, LTH 1367", + month = "4", + year = "2024" } diff --git a/doc/source/theory/Matching.rst b/doc/source/theory/Matching.rst index 5089c0a95..fa84cab16 100644 --- a/doc/source/theory/Matching.rst +++ b/doc/source/theory/Matching.rst @@ -88,11 +88,11 @@ During the matching we use :math:`a_s^{(n_f+1)}`: in fact the :math:`a_s` decoup :math:`\ln(\mu_{h}^2/m_{h}^2)`, which are cancelled by the OME's :math:`A_{kl,H}`. |N3LO| matrix elements have been presented in :cite:`Bierenbaum:2009mv` and following publications -:cite:`Ablinger:2010ty,Ablinger:2014vwa,Ablinger:2014uka,Behring:2014eya,Blumlein:2017wxd,Ablinger_2014,Ablinger_2015,Ablinger:2022wbb`. +:cite:`Ablinger:2010ty,Ablinger:2014vwa,Ablinger:2014uka,Behring:2014eya,Blumlein:2017wxd,Ablinger_2014,Ablinger_2015,Ablinger:2022wbb,Ablinger:2024xtt`. Parts proportional to :math:`\ln(\mu_{h}^2/m_{h}^2)` are also included up to |N3LO|. -The contribution of :math:`A_{Hg}^{(3)}` is not yet fully known analytically and has been parameterized using the first 5 known -moments :cite:`Bierenbaum:2009mv` and the |LL| small-x contribution :cite:`Kawamura:2012cr` +All the contributions are now known analytically. Due to the lengthy and complex expressions +some parts of :math:`A_{Hg}^{S,(3)},A_{Hq}^{S,(3)},A_{gg}^{S,(3)},A_{qq}^{NS,(3)}` have been parameterized. We remark that contributions of the heavy quark initiated diagrams at |NNLO| and |N3LO| have not been computed yet, thus the elements :math:`A_{qH}^{(2)},A_{gH}^{(2)}A_{HH}^{(2)}` are not encoded in EKO despite of being present. diff --git a/doc/source/theory/N3LO_ad.rst b/doc/source/theory/N3LO_ad.rst index 34030f7e7..1fb13a15e 100644 --- a/doc/source/theory/N3LO_ad.rst +++ b/doc/source/theory/N3LO_ad.rst @@ -264,7 +264,8 @@ The other parts are approximated using some known limits: & \gamma_{qg}(2) + \gamma_{gg}(2) = 0 \\ & \gamma_{qq}(2) + \gamma_{gq}(2) = 0 \\ - For :math:`\gamma_{qq,ps}, \gamma_{qg}` other 5 additional moments are available :cite:`Falcioni:2023luc,Falcioni:2023vqq`. + For :math:`\gamma_{qq,ps}, \gamma_{qg},\gamma_{gq}` other 5 additional moments are available from + :cite:`Falcioni:2023luc,Falcioni:2023vqq,Falcioni:2024xyt` respectively. making the parametrization of this splitting function much more accurate. The difference between the known moments and the known limits is parametrized @@ -337,7 +338,7 @@ final reduced sets of candidates. * - :math:`f_4(N)` - :math:`\frac{1}{N^4},\ \frac{1}{N^3},\ \frac{1}{N^2},\ \frac{1}{(N+1)},\ \frac{1}{(N+2)},\ \mathcal{M}[\ln^2(1-x)],\ \mathcal{M}[\ln(1-x)]` - Following :cite:`Moch:2023tdj` we have assumed no violation of the scaling with :math:`\gamma_{gg}` + Following :cite:`Moch:2023tdj,Falcioni:2024xyt` we have assumed no violation of the scaling with :math:`\gamma_{gg}` also for the |NLL| small-x term, to help the convergence. We expect that any possible deviation can be parametrized as a shift in the |NNLL| terms which are free to vary independently. diff --git a/extras/lh_bench_23/.gitignore b/extras/lh_bench_23/.gitignore index 2942ad98d..79e096ab2 100644 --- a/extras/lh_bench_23/.gitignore +++ b/extras/lh_bench_23/.gitignore @@ -1,3 +1,4 @@ *.tar *.csv *.dat +*.tex diff --git a/extras/lh_bench_23/cfg.py b/extras/lh_bench_23/cfg.py index ef7c747ef..c3700687d 100644 --- a/extras/lh_bench_23/cfg.py +++ b/extras/lh_bench_23/cfg.py @@ -62,10 +62,12 @@ def vfns_theory(xif=1.0): ] -def ffns_theory(xif=1.0): +def ffns_theory(xif=1.0, pto=2): """Generate a VFNS theory card.""" tt = copy.deepcopy(_t_ffns) tt["xif"] = xif + tt["order"] = (pto + 1, 0) + tt["matching_order"] = (pto, 0) return runcards.TheoryCard.from_dict(tt) @@ -107,9 +109,15 @@ def n3lo_theory(ad_variation, is_ffns, use_fhmruvv=False, xif=1.0): ) vfns_operator = runcards.OperatorCard.from_dict(_o_vfns) -_o_ffns = copy.deepcopy(_o_vfns) -_o_ffns["mugrid"] = [(100.0, 4)] -ffns_operator = runcards.OperatorCard.from_dict(_o_ffns) + +def ffns_operator(ev_method="iterate-exact"): + """Generate a FFNS theory card.""" + op = copy.deepcopy(_o_vfns) + op["mugrid"] = [(100.0, 4)] + op["configs"]["evolution_method"] = ev_method + if ev_method == "truncated": + op["configs"]["ev_op_iterations"] = 1 + return runcards.OperatorCard.from_dict(op) # flavor rotations diff --git a/extras/lh_bench_23/parse_to_latex.py b/extras/lh_bench_23/parse_to_latex.py new file mode 100644 index 000000000..7f59ddc2b --- /dev/null +++ b/extras/lh_bench_23/parse_to_latex.py @@ -0,0 +1,179 @@ +from cfg import here, table_dir, xgrid +from utils import compute_n3lo_avg_err, load_n3lo_tables + +n3lo_table_dir = table_dir + +latex_tab = here / "latex_tab" +latex_tab.mkdir(exist_ok=True) + +SVS = ["central", "up", "down"] + +MIDRULE1 = r""" +\hline \hline +\multicolumn{9}{||c||}{} \\[-3mm] +\multicolumn{9}{||c||}{""" + +MIDRULE2 = r"""} \\ +\multicolumn{9}{||c||}{} \\[-0.3cm] +\hline \hline + & & & & & & & \\[-0.3cm] +""" + +BOTTOMRULE = r""" +\hline \hline +\end{tabular} +\end{center} +\end{table} +""" + +VFNS_LABELS = r""" + \multicolumn{1}{c|} {$xu_v$} & + \multicolumn{1}{c|} {$xd_v$} & + \multicolumn{1}{c|} {$xL_-$} & + \multicolumn{1}{c|} {$xL_+$} & + \multicolumn{1}{c|} {$xs_+$} & + \multicolumn{1}{c|} {$xc_+$} & + \multicolumn{1}{c|} {$xb_+$} & + \multicolumn{1}{c||}{$xg$} \\[0.5mm] + """ + +FFNS_LABELS = r""" + \multicolumn{1}{c|} {$xu_v$} & + \multicolumn{1}{c|} {$xd_v$} & + \multicolumn{1}{c|} {$xL_-$} & + \multicolumn{1}{c|} {$xL_+$} & + \multicolumn{1}{c|} {$xs_v$} & + \multicolumn{1}{c|} {$xs_+$} & + \multicolumn{1}{c|} {$xc_+$} & + \multicolumn{1}{c||}{$xg$} + """ + + +def insert_headrule(scheme, approx, caption): + """Insert the middle rule.""" + label = r"\label{tab:" + f"n3lo_{scheme.lower()}_{approx.lower()}" + "}" + scheme_label = ( + r", $\, N_{\rm f} = 3\ldots 5\,$," + if scheme == "VFNS" + else r"$\, N_{\rm f} = 4$," + ) + HEADRULE = ( + r""" + \begin{table}[htp] + \caption{""" + + caption + + r"""} + """ + + label + + r""" + \begin{center} + \vspace{5mm} + \begin{tabular}{||c||r|r|r|r|r|r|r|r||} + \hline \hline + \multicolumn{9}{||c||}{} \\[-3mm] + \multicolumn{9}{||c||}{""" + # + r"""aN$^3$LO, """ + + approx + + scheme_label + + r"""$\,\mu_{\rm f}^2 = 10^4 \mbox{ GeV}^2$} \\ + \multicolumn{9}{||c||}{} \\[-0.3cm] + \hline \hline + \multicolumn{9}{||c||}{} \\[-3mm] + \multicolumn{1}{||c||}{$x$} & + """ + ) + HEADRULE += VFNS_LABELS if scheme == "VFNS" else FFNS_LABELS + HEADRULE += r"""\\[0.5mm]""" + return HEADRULE + + +def insert_midrule(sv): + """Insert the middle rule.""" + # TODO: is this mapping correct or the other way round ?? + # xif2 = 2 -> up + # xif2 = 1/2 -> down + label = { + "central": r"$\mu_{\rm r}^2 = \ \mu_{\rm f}^2$", + "down": r"$\mu_{\rm r}^2 = 0.5 \ \mu_{\rm f}^2$", + "up": r"$\mu_{\rm r}^2 = 2 \ \mu_{\rm f}^2$", + } + return MIDRULE1 + label[sv] + MIDRULE2 + + +def format_float(values): + """Clean float format.""" + values = values.replace("0000", "0") + values = values.replace("e-0", "$^{-") + values = values.replace("e-10", "$^{-10") + values = values.replace("e+0", "$^{+") + values = values.replace("&", "}$ &") + values = values.replace(r"\\", r"}$ \\") + return values + + +def dump_table(scheme: str, approx: str, caption: str): + """Write a nice latex table.""" + final_tab = insert_headrule(scheme, approx.replace("EKO", "NNPDF"), caption) + # loop on scales + for sv in SVS: + # load tables + dfs = load_n3lo_tables(n3lo_table_dir, scheme, sv=sv, approx=approx) + + central, err = compute_n3lo_avg_err(dfs) + + central.insert(0, "x", xgrid) + values = central.to_latex(float_format="{:.4e}".format, index=False) + values = "".join(e for e in values.split("\n")[4:-3]) + final_tab += insert_midrule(sv) + format_float(values) + + final_tab += BOTTOMRULE + + # write + with open( + latex_tab / f"table-{scheme}-{approx.replace('EKO', 'NNPDF')}.tex", + "w", + encoding="utf-8", + ) as f: + f.writelines(final_tab) + + +if __name__ == "__main__": + approx = "FHMRUVV" + scheme = "FFNS" + caption = r""" + Results for the FFNS aN$^3$LO evolution + for the initial conditions and the input parton distributions + given in Sec.~\ref{sec:toy_pdf}, + with the FHMRUVV splitting functions approximation and the NNPDF code. + """ + dump_table(scheme, approx, caption) + + approx = "FHMRUVV" + scheme = "VFNS" + caption = r""" + Results for the VFNS aN$^3$LO evolution + for the initial conditions and the input parton distributions + given in Sec.~\ref{sec:toy_pdf}, + with the FHMRUVV splitting functions approximation and the NNPDF code. + """ + dump_table(scheme, approx, caption) + + approx = "EKO" + scheme = "FFNS" + caption = r""" + Results for the FFNS aN$^3$LO evolution + for the initial conditions and the input parton distributions + given in Sec.~\ref{sec:toy_pdf}, + with the NNPDF splitting functions approximation. + """ + dump_table(scheme, approx, caption) + + approx = "EKO" + scheme = "VFNS" + caption = r""" + Results for the VFNS aN$^3$LO evolution + for the initial conditions and the input parton distributions + given in Sec.~\ref{sec:toy_pdf}, + with the NNPDF splitting functions approximation. + """ + dump_table(scheme, approx, caption) diff --git a/extras/lh_bench_23/plot_bench.py b/extras/lh_bench_23/plot_bench.py deleted file mode 100644 index 6887e7ac3..000000000 --- a/extras/lh_bench_23/plot_bench.py +++ /dev/null @@ -1,49 +0,0 @@ -from cfg import here, table_dir, xgrid -from utils import ( - compute_n3lo_avg_err, - compute_n3lo_nnlo_diff, - load_n3lo_tables, - load_nnlo_table, - plot_diff_to_nnlo, - plot_pdfs, -) - -USE_LINX = True -REL_DIFF = True -SCHEME = "VFNS" -SV = "central" - -plot_dir = here / "plots" -n3lo_table_dir = table_dir # / SCHEME - - -# load tables -eko_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, approx="EKO") -fhmv_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, approx="FHMV") -nnlo_central = load_nnlo_table(table_dir, SCHEME, SV) - -# compute avg and std -eko_res = compute_n3lo_avg_err(eko_dfs) -fhmv_res = compute_n3lo_avg_err(fhmv_dfs) -# eko_4mom_res = = compute_n3lo_avg_err(eko_dfs_4mom) - -n3lo_dfs = [ - (eko_res, "aN3LO EKO"), - (fhmv_res, "aN3LO FHMV"), - # (eko_4mom_res, "aN3LO EKO 4 mom"), -] - -# PDFs plots -plot_pdfs(xgrid, n3lo_dfs, nnlo_central, SCHEME, USE_LINX, plot_dir) - -# relative diff plots -eko_diff = compute_n3lo_nnlo_diff(eko_res, nnlo_central, REL_DIFF) -fhmv_diff = compute_n3lo_nnlo_diff(fhmv_res, nnlo_central, REL_DIFF) -n3lo_dfs = [ - (eko_diff, "aN3LO EKO"), - (fhmv_diff, "aN3LO FHMV"), - # (eko_4mom_res, "aN3LO EKO 4 mom"), -] - -# relative, absolute diff plots -plot_diff_to_nnlo(xgrid, n3lo_dfs, SCHEME, USE_LINX, plot_dir, REL_DIFF) diff --git a/extras/lh_bench_23/plot_bench_evol.py b/extras/lh_bench_23/plot_bench_evol.py index 92972af14..af25f5c65 100644 --- a/extras/lh_bench_23/plot_bench_evol.py +++ b/extras/lh_bench_23/plot_bench_evol.py @@ -18,17 +18,21 @@ # load tables -eko_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, approx="EKO", rotate_to_evol=True) -fhmv_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, approx="FHMV", rotate_to_evol=True) +eko_dfs = load_n3lo_tables( + n3lo_table_dir, SCHEME, sv="central", approx="EKO", rotate_to_evol=True +) +fhmruvv_dfs = load_n3lo_tables( + n3lo_table_dir, SCHEME, sv="central", approx="FHMRUVV", rotate_to_evol=True +) nnlo_central = load_nnlo_table(table_dir, SCHEME, SV, rotate_to_evol=True) # compute avg and std eko_res = compute_n3lo_avg_err(eko_dfs) -fhmv_res = compute_n3lo_avg_err(fhmv_dfs) +fhmruvv_res = compute_n3lo_avg_err(fhmruvv_dfs) n3lo_dfs = [ (eko_res, "aN3LO EKO"), - (fhmv_res, "aN3LO FHMV"), + (fhmruvv_res, "aN3LO FHMRUVV"), ] # absolute plots @@ -36,10 +40,10 @@ # relative, absolute diff plots eko_diff = compute_n3lo_nnlo_diff(eko_res, nnlo_central, REL_DIFF) -fhmv_diff = compute_n3lo_nnlo_diff(fhmv_res, nnlo_central, REL_DIFF) +fhmruvv_diff = compute_n3lo_nnlo_diff(fhmruvv_res, nnlo_central, REL_DIFF) n3lo_dfs = [ (eko_diff, "aN3LO EKO"), - (fhmv_diff, "aN3LO FHMV"), + (fhmruvv_diff, "aN3LO FHMRUVV"), ] plot_diff_to_nnlo(xgrid, n3lo_dfs, SCHEME, USE_LINX, plot_dir, REL_DIFF) diff --git a/extras/lh_bench_23/plot_bench_msht.py b/extras/lh_bench_23/plot_bench_msht.py index 0314082ee..f99c4c613 100644 --- a/extras/lh_bench_23/plot_bench_msht.py +++ b/extras/lh_bench_23/plot_bench_msht.py @@ -15,48 +15,51 @@ SV = "central" plot_dir = here / "plots_msht" -n3lo_table_dir = table_dir # / SCHEME +n3lo_table_dir = table_dir msht_table_dir = table_dir # load tables -eko_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, approx="EKO") -fhmv_eko_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, approx="FHMV") -msht_dfs = load_msht(msht_table_dir, SCHEME, approx="MSHT") -fhmv_msht_dfs = load_msht(msht_table_dir, SCHEME, approx="FHMV") +eko_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, SV, approx="EKO") + +fhmruvv_eko_dfs = load_n3lo_tables(n3lo_table_dir, SCHEME, SV, approx="FHMRUVV") +fhmruvv_msht_dfs = load_msht(msht_table_dir, SCHEME, approx="FHMRUVV") + +msht_post_dfs = load_msht(msht_table_dir, SCHEME, approx="MSHTposterior") +msht_prior_dfs = load_msht(msht_table_dir, SCHEME, approx="MSHTprior") nnlo_central = load_nnlo_table(table_dir, SCHEME, SV) # compute avg and std eko_res = compute_n3lo_avg_err(eko_dfs) -fhmv_eko_res = compute_n3lo_avg_err(fhmv_eko_dfs) -msht_res = compute_n3lo_avg_err(msht_dfs) -fhmv_msht_res = compute_n3lo_avg_err(fhmv_msht_dfs) -# eko_4mom_res = = compute_n3lo_avg_err(eko_dfs_4mom) +fhmruvv_eko_res = compute_n3lo_avg_err(fhmruvv_eko_dfs) +fhmruvv_msht_res = compute_n3lo_avg_err(fhmruvv_msht_dfs) +msht_post_res = compute_n3lo_avg_err(msht_post_dfs) +msht_prior_res = compute_n3lo_avg_err(msht_prior_dfs) -n3lo_dfs = [ - (eko_res, "EKO"), - (fhmv_eko_res, "FHMV EKO"), - (msht_res, "MSHT"), - (fhmv_msht_res, "FHMV MSHT") - # (eko_4mom_res, "aN3LO EKO 4 mom"), -] +# compute average of FHMRUVV +fhmruvv_res = [] +for a, b in zip(fhmruvv_msht_res, fhmruvv_eko_res): + fhmruvv_res.append((a + b) / 2) # PDFs plots +n3lo_dfs = [ + (fhmruvv_res, "FHMRUVV"), + (msht_prior_res, "MSHT (prior)"), + (msht_post_res, "MSHT (posterior)"), + (eko_res, "NNPDF"), +] plot_pdfs(xgrid, n3lo_dfs, nnlo_central, SCHEME, USE_LINX, plot_dir) -# relative diff plots +# relative, absolute diff plots eko_diff = compute_n3lo_nnlo_diff(eko_res, nnlo_central, REL_DIFF) -fhmv_eko_diff = compute_n3lo_nnlo_diff(fhmv_eko_res, nnlo_central, REL_DIFF) -msht_diff = compute_n3lo_nnlo_diff(msht_res, nnlo_central, REL_DIFF) -fhmv_msht_diff = compute_n3lo_nnlo_diff(fhmv_msht_res, nnlo_central, REL_DIFF) +fhmruvv_diff = compute_n3lo_nnlo_diff(fhmruvv_res, nnlo_central, REL_DIFF) +msht_prior_diff = compute_n3lo_nnlo_diff(msht_prior_res, nnlo_central, REL_DIFF) +msht_post_diff = compute_n3lo_nnlo_diff(msht_post_res, nnlo_central, REL_DIFF) n3lo_dfs = [ - (eko_diff, "EKO"), - (fhmv_eko_diff, "FHMV EKO"), - (msht_diff, "MSHT"), - (fhmv_msht_diff, "FHMV MSHT") - # (eko_4mom_res, "aN3LO EKO 4 mom"), + (fhmruvv_diff, "FHMRUVV"), + (msht_prior_diff, "MSHT (prior)"), + (msht_post_diff, "MSHT (posterior)"), + (eko_diff, "NNPDF"), ] - -# relative, absolute diff plots plot_diff_to_nnlo(xgrid, n3lo_dfs, SCHEME, USE_LINX, plot_dir, REL_DIFF) diff --git a/extras/lh_bench_23/plot_trn_exa.py b/extras/lh_bench_23/plot_trn_exa.py new file mode 100644 index 000000000..7558cedab --- /dev/null +++ b/extras/lh_bench_23/plot_trn_exa.py @@ -0,0 +1,64 @@ +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +from cfg import table_dir, xgrid +from utils import HERE, lha_labels + +from eko.io.types import EvolutionMethod + +plt.style.use(HERE / "plotstyle.mplstyle") +plot_dir = HERE / "plots_trn_exa" + +PTOS = {1: "NLO", 2: "NNLO", 3: "N$^3$LO"} + +COLUMNS_TO_KEEP = ["L_m", "L_p", "g"] + + +def load_table(method): + """Load tables.""" + dfs = {} + for pto in PTOS: + with open(table_dir / f"table_FFNS-{pto}_{method}.csv", encoding="utf-8") as f: + dfs[pto] = pd.read_csv(f, index_col=0) + return dfs + + +def plot_diff(xgrid, dfs_trn, dfs_exa): + cut_smallx = 0 + cut_largex = -1 + xgrid = xgrid[cut_smallx:cut_largex] + + plot_dir.mkdir(exist_ok=True) + + # loop on PDFs + for column in COLUMNS_TO_KEEP: + _, ax = plt.subplots(1, 1, figsize=(1 * 5, 1 * 3.5)) + j = np.where(dfs_trn[1].columns == column)[0][0] + + # loop on ptos + for pto, pto_label in PTOS.items(): + diff = (dfs_trn[pto] - dfs_exa[pto]) / dfs_trn[pto] * 100 + + ax.plot(xgrid, diff.values[cut_smallx:cut_largex, j], label=pto_label) + ax.hlines( + 0, + xgrid.min() - xgrid.min() / 3, + 1, + linestyles="dotted", + color="black", + linewidth=0.5, + ) + ax.set_xscale("log") + ax.set_xlabel("$x$") + ax.set_ylabel(f'${lha_labels("FFNS")[j]}$') + ax.set_xlim(xgrid.min() - xgrid.min() / 3, 1) + + plt.legend() + plt.tight_layout() + plt.savefig(f"{plot_dir}/diff_trn_exa_{column}.pdf") + + +if __name__ == "__main__": + dfs_trn = load_table(EvolutionMethod.TRUNCATED.value) + dfs_exa = load_table(EvolutionMethod.ITERATE_EXACT.value) + plot_diff(xgrid, dfs_trn, dfs_exa) diff --git a/extras/lh_bench_23/run-n3lo.py b/extras/lh_bench_23/run-n3lo.py index 4ee00d520..8098f28dc 100644 --- a/extras/lh_bench_23/run-n3lo.py +++ b/extras/lh_bench_23/run-n3lo.py @@ -76,7 +76,7 @@ use_fhmruvv=args.use_fhmruvv, xif=xif, ) - o = ffns_operator + o = ffns_operator() tab = 14 lab = ffns_labels rot = ffns_rotate_to_LHA diff --git a/extras/lh_bench_23/run-nnlo.py b/extras/lh_bench_23/run-nnlo.py index 85ab2f984..9f5c681cc 100644 --- a/extras/lh_bench_23/run-nnlo.py +++ b/extras/lh_bench_23/run-nnlo.py @@ -3,7 +3,6 @@ import pathlib import sys -import numpy as np import pandas as pd import yaml from banana import toy @@ -63,7 +62,7 @@ if args.scheme == "FFNS": scheme = "FFNS" t = ffns_theory(xif) - o = ffns_operator + o = ffns_operator() tab = 14 lab = ffns_labels rot = ffns_rotate_to_LHA diff --git a/extras/lh_bench_23/run-trn_exa.py b/extras/lh_bench_23/run-trn_exa.py new file mode 100644 index 000000000..97d1a1cf5 --- /dev/null +++ b/extras/lh_bench_23/run-trn_exa.py @@ -0,0 +1,72 @@ +import logging +import pathlib +import sys + +import pandas as pd +from banana import toy +from cfg import ( + ffns_labels, + ffns_operator, + ffns_rotate_to_LHA, + ffns_theory, + n3lo_theory, + table_dir, + xgrid, +) + +import eko +from eko.io.types import EvolutionMethod +from eko.runner.managed import solve +from ekobox import apply + +stdout_log = logging.StreamHandler(sys.stdout) +logger = logging.getLogger("eko") +logger.handlers = [] +logger.setLevel(logging.INFO) +logger.addHandler(stdout_log) + + +def compute(op_card, th_card): + rot = ffns_rotate_to_LHA + lab = ffns_labels + + method = op_card.configs.evolution_method.value + pto = th_card.order[0] - 1 + path = pathlib.Path(f"ekos/FFNS-{pto}_{method}.tar") + path.unlink(missing_ok=True) + + solve(th_card, op_card, path) + + # apply PDF + out = {} + with eko.EKO.read(path) as eko_: + pdf = apply.apply_pdf_flavor(eko_, toy.mkPDF("ToyLH", 0), xgrid, rot, lab) + for lab, f in list(pdf.values())[0]["pdfs"].items(): + out[lab] = xgrid * f + + # display result + pd.set_option("display.float_format", "{:.4e}".format) + me = pd.DataFrame(out) + print("EKO") + print(me) + # dump to file + table_dir.mkdir(exist_ok=True) + me.to_csv(f"{table_dir}/table_FFNS-{pto}_{method}.csv") + + +if __name__ == "__main__": + # loop on ev methods + for ev_method in [EvolutionMethod.TRUNCATED, EvolutionMethod.ITERATE_EXACT]: + op_card = ffns_operator(ev_method=ev_method.value) + # loop on pto + for pto in [1, 2, 3]: + if pto == 3: + th_card = n3lo_theory( + ad_variation=(0, 0, 0, 0, 0, 0, 0), + is_ffns=True, + use_fhmruvv=True, + xif=1.0, + ) + else: + th_card = ffns_theory(xif=1.0, pto=pto) + compute(op_card, th_card) diff --git a/extras/lh_bench_23/run_fhmv.sh b/extras/lh_bench_23/run_fhmruvv.sh similarity index 76% rename from extras/lh_bench_23/run_fhmv.sh rename to extras/lh_bench_23/run_fhmruvv.sh index 45807ea4d..a9c572ea8 100755 --- a/extras/lh_bench_23/run_fhmv.sh +++ b/extras/lh_bench_23/run_fhmruvv.sh @@ -1,12 +1,12 @@ #!/bin/bash -SCHEME="FFNS" -SV="central" +SCHEME="VFNS" +SV="up" AD_VAR=(0 0 0 0 0 0 0) # run the central -python run-n3lo.py $SCHEME $SV "${AD_VAR[@]}" "--use_fhmv" +python run-n3lo.py $SCHEME $SV "${AD_VAR[@]}" "--use_fhmruvv" # loop on gammas for I in {0..6} @@ -15,7 +15,7 @@ for I in {0..6} for VAR in {1..2} do AD_VAR[$I]=$VAR - python run-n3lo.py $SCHEME $SV "${AD_VAR[@]}" "--use_fhmv" + python run-n3lo.py $SCHEME $SV "${AD_VAR[@]}" "--use_fhmruvv" AD_VAR[$I]=0 done done diff --git a/extras/lh_bench_23/tables/EKO.zip b/extras/lh_bench_23/tables/EKO.zip new file mode 100644 index 0000000000000000000000000000000000000000..66a797e7af18ff15c7a337b8d79e08d3594a6acf GIT binary patch literal 742394 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

l-C1#4_#L#SlpyS9e7$9k@DzAqn^QLi&5!zgoh> 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

<|9UX+N96qTm!TmdVQByN+~ZO~d6P!p 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 Pd+hJjsj{`sEdK5PZARJe literal 0 HcmV?d00001 diff --git a/extras/lh_bench_23/tables/MSHT.zip b/extras/lh_bench_23/tables/MSHT.zip new file mode 100644 index 0000000000000000000000000000000000000000..f8b21d7e325fe0a36c4c9cf35a9f949e50f3b14c GIT binary patch literal 99712 zcmdSB1#nzjlCCRev@B+3$zo=*n3)O z&M2a!imK4sYv<1O?Z5t&Su*0lAfEw#{iuEYsq)*CfByvvfCnHc|5brjQ2`bJ9Q&)O z(SJM~U7!H~L2dy70Dk*dncs$h0D$<5A@V+kf&UmnTU(M(Kw4gfmPY&6Xn!%7=&HZb ze;G_)2U*`(M^EQMQbOqhUMWPz2Pg&&m=pmM&=w!T{~;Vb1Skq0pHGJ5>i`Vip0Ip( z2m-3)*!ZkC71^NZEG5}6t@x<;PjM+j9Rod9r_n3%ch`G202y&`2=p^9ETxZ0{hHYC zPZ+1_p zqC#%ySG{j=a2REPpT0sKNo8Qa&|5`4!8%;HH?pF&eW%@%fNw%UifrYX;*7a-ZQ8H! zZUpuz(h^3_f$0=38KbXVs5Pwmic}NhwSmTTk`o17dsBxNq>C2xXedZ=m$1*>^95SM z&f7+mYs$97?@m3RxNkeAIUnbcRgrH%HJ?~6eFoq0w>KT8KQTTc+>H7ek#&E()TR-O zZuITz-Wlb>0Lk6N1HCu=F6E;}yt}_w;irs#e_b;uOrr|Eljl>fl_Zg6X_3sy)90R~ zVg`x>ET`F|HJu>JnO*btw5Ayk=X>FDn3~5cHm1k9&&t@oH%xSb5%wAzFoZWd&yzFN zoIkbsMqleEGi$k>6A!>keoo>pRa>h*QWm{ldSr5h?q!f^2~FdcE+}I;4GI9^OGW;odGKp4;1JLuovchBNB=d0f1BIK z6MzfbhQC;gsQ;0bQVbH(+QMHY;S3SKIVTX?6u zU2W)Cx^?w@dmFfYWZ>cP(ztuvzMtQ>e!0f<_TJi0wpQ3l>hRQjqA5CCnnLIC2qAJz zyt&ZSVTwJR?4H1E>2@7~IPn>4c0~R-Q|_l-GJ20Xn5-CI;M@W3n3| zq`z@SNX+|{37Aeqc^QbBI3b(R-_{iXL6%aTSV03*0*a;V42s;TUCpZe64X$#A<5fO z+29Li7>8vAX4X9rvy?D{sxehZS6iQi!B`JuVFg1HaQRaaFx(jTv)9}Bl2pe9IbNsf z2^&WWEUGb;#QsFv614dBYJ%RiELSu-NQRVOUJu3vsT)-i4U7hUuvmv6KoVgn5} ziJ(>7Ont;wa1-D6;sJ_?auK=5H-zc;${LpMguh-yGZxtP4NUZQn|j?_tQq4pnUg#9 znT6CE=&E?5?0>PvwZ`72TNg*&Xs3xeE*41mS9cAEUwN*P5r^lx6HnlvLWd zXLxVs-a88(Mn+P}w>^H&1SlVc1{{RI#96jWMFfw>!zvH4*HaNf?ob@2oEs@D0Tk5>*xyuyC4y5$K-u}i3@5jhJ_oK=X?$Crf{RuoXg&A zR8J1KGRK@&UCKriR(9(-B)wl!uWl?4G{%0&rLXellkSdVKJhT;zh#jjS?IAFBw9c+lR&^?nejj6U8T@2H4ge|X!q zJshCr(Ztn$+@|dC-hIBO72iqn_S8J~tWt6srg?wFm&>3fw;ypDUDBi9_v*8h8|~@B zOiLTTZalJbE>SrNQ3~bSccngdFRVnabE1UTgl`)$6cSQzN+> zZ#r2~vY(t=T3UBo&D9+m15(MY1L&(v|q&o{pCq*^?jI{#TjvE@H#DLGN8gPUYSt7GXMltS{St2 zMR7WYh~q)e7L9;itWZ8?%>BG-u~2k7E_$dX3^6O`?|HGnMYajD?dDzG6oP$?hFoR2 z+fMDLB6Wxe8cYN6hy%fj8^RSpq9uUlWa_(51+UpSCJ4!j-Gr3}lFk9i2-*T&1Q%0P zusDmoR4bF-_M=&6J8=JDBgyoWVwKlawx!vgqzuxp+9O_uX(@N1W&n18*z7rmq~SIv z0c*gcb;}J6bR+BG5EiNam}`uHB2}7vNasOEp*uXLYr+J!Y(206q}kVbz^nDD_@VI~ z`;<|_?(}fokE-yqZ&j#sCW8WKNRO(Vg|T#oPoiBl#b$#hoB$EJY|vrnl$+gdZLh}Y zbe&ARbBy*en#(%9z?NzEtnrOAetHBtXd|Fq2aOJBPG~4bZb9`*)5i59{|=8a0JZcz z^qT?Kt{?{kht(ZX0OI?yg{arf39DA>XAh1*5TSSGsXL;}UpxmPAvtrnT092Pt$Oye z0XLQyG^e>tSSO&RUUfQ@8}raN_kZ9jVPRR*2g7u4Rp?Va=s_t&sN zt&Ao24n**6nwmn@!6Sd@{oWB3f&SN6@Qv~P6XkrO1S*lrJSIj_fNkw7;J#O2O7~>O zkwd=gI!c`Q5{fU_MJFj=3Q2+^Z%mRanvOFBxT7U?#$8 zsLZ|9tWMx#0Bki#Q z8F^x8K6by`P)>#8v^Fu}lJ%VEd@6~&Y{fAuw9iRnYehE3%*5ZYcss#yf225K=~{OB zT2g(UNvT-iBug=u*k6N_q=sHHvJHa>!QpVdI$LiR+}>G71JIjE3u6beR*kl zZGT$(seY^N4fMhYb zWUT;DF_K%%{?%JWDjlWAK0WGSDNBE*lxzcE+@r@!b;P&sJmFKpWo%?lB5-(rzz;>l z(4^^Ly7;KWRR;9OCOcqfeE&~N$N?606^-@@qe6Z@@;wz=4F<@>Y1*90JPz|?u*{#G zmu^~CdqhrKm$Dpn(D}P8AUtK`n-18LeGSRg(bA&Xr7|1qj02kKD5-3A_l6}$i*q2n zJ9Ko}1(H*kC+C5nMGjEX;&f3*ADdyi3v!)N7_bT7ZPd_PK3ldfXorXq^`y>zwn=CB zCL-@|f=rB_MM4B$h5MU4Z>?;|tuO%#_I0wzuFA=$hcud#Z-vitOde?j?Xo4T9M^1> z>Zl&Vz!0b*1J%&zI2dNgzhMw`cpT&NgDMEM+iR?YqCh{7U<1?j6G5e*^uL`%>C56` zW*8G9%luaE4)!B|2=2r`?Dm7_DO{KGlF@UIL4>{GCZJPUhC0N`D zb?i-Aa`lUu==oZ+4#I_J;u;9oA}n%!f+5mwwC_PQ6vw+?3%F@J_==^ERf;^cR%7v< zho;Y!5h1T2j3uj@GmF41RA}!a>Iw3x+d7{qgnHa0P_B%{lpRX#05I_6_-CZ`ZX0Mun+|dXIYxKDXR4c#wx`G92iI|(% zfkQjONO*Y{CXORT1o7&O_L?hmk|?I4VM1E{bkTW}8Al~rC=#-@!IsVnx$oG(x5sovlo(7JZ z?zXTKzM9m}M~crMX0G+M6{~j)IE$E<;Fu02xy_lC+NDcCck?%BSl0*00SkK6A9&pf z>${Q{T=@hkXF{IVXp+4TS}C(rR@deYb41M^KB3d-n10awtcGeS>4vc{!){Bquv_0I zDN2}snR!~-<4Bw(P(sF|$9&{zM#s;^w&G`^fN7n|?j(e#9CTSgg~QS`$`4WyE-~-~ zmx*C$FBI3_Xg&-8Z?XC4stkHl75@6+kcwNrJPjeB=$dGC%B>^&o*#*YaKl3&ybZmu z#}E7gG37G#fMi9pnr$O+&YEpGNmGV(fUM^^$W z>)%JFI)k>(=soF(Hxc?r3D28#59t}3gqWF%42Q9KfW_lc_|x+EJFa{6idH)18CQlg z;A}A2Nd0}fv#QY81Eq=}5q-x62C@7O-6&}(p?Fbaisv@q*~xhfDgA><<~7HJ750hr zwrWhuq$0X(kqahGG+#M`CS+2_Qtg%p&h`!Q1r52G+q?IR>7eC?Q`<$Pui7t96l)nK znqxYo91+58i4q2QccV5c)CO$wQZ1fV8<#{vimrD3=e7eyLYnm1geViUjAvJTh`s=c z`6H}Y)C&C&iG&?sKyZq$M>qcT9ZwESu5i~{45)FytAtMZ)T4_nST-QKqMJuzya=RD z*x7;y^xKsf%ppS5a>*mwO)!=1`^XYG+P<5^S8Uo~W|(ibgsEsHxr;rjM7z6R{iR`` zZK3Uyqto#VNLSk@>GgfKu4o`N`VIrwb`Am^&H$~xiz2cfVguV2D-+xVh5JlknK7KR zQg*`ia8!{_Q?I{w?YqB|g2B6gUw2|n3X|47)nPsv_bczYX$_*jh)%;EAVgDWBMDrF z7wh($B>3){%)IgqzfgJsu;0=Z^IOd`82xhDsHB$G@QfV{8(>ugH|O@(xVq#z1b>17U2buyK*4Mm-wNIC~@=u68f7tE_B$cs!y0 zhH}>lJ+pru%6}Jn|NBvH`$wJgzd$*>#T(-gu))4M5$~LDtWH#RwAqkwOf@3l6ff87 zLYbaoo!8r;blY0xeaBn-n)m+ec!$Qh_QO?RN5|#c_VlNwUF}NqHk7%gx`JtM zPbAT~nyVXTK`r{9?C9ZF819G()_tC${rFi8M}b~ZvJ~6B{8;kb z!IT^_eqn2J9OL-zWE4kMz4)8*a3q)A_Ab4k2ap-lKyj2<3H8twZ#qwBwC1 z4$6FX=l&ljMgAjavvHr}B@6Y|=L($F(~3h?4rYSkEuZ%{W8WV3y)b0p1I@9c`?>1Gf-M+F)29n3W9;~Nq z8=c#&4=wbrYJGU;W2Qf4@0DAf7~qvLiI6$MC+YpB%x;Gb-IwiapOb8cV1qy{<>tfO zqan~DnNF!%6uPQfJ)*l=<==S9awO4)W-Zxs&D|qpD{}$#J{6f?`}F{ioNLrM_|Az~ zTm{q#2ZkWKA?gYeMJ)1L98uDvKeA2vQc}XY8nMs|)y=nW79xCCqoY>$Qe4Nhi@?`I zn!5=;yK<=d);Mjnf?W$JkO4ET3XZaqC+f=(H6T)K>)j&_huIQ9 z#ci&VTE~Pui>HSFWv(aSEb?{1A9gEXj4{8(U=q(yFYhJ*lsGYzC@XEt^I}l5>#QI& z1kfV03}32tV1b~nn$Eu&l^wrZqPZY;L?qm0g` z4lbGxXI*p8)JTThy{K(OiR)Q%!Qhz(c1TtW zN450DOKhY~alMRIE~HqtM4N#^N5^hKh;b239%dk-L|Gg+91I`M z`3wo#hV#?53|gKqms-hdH$&1modQz$&rRf8q#KarNnaCeG5?D%yxc2E;UkBRi5;V> z<7Cydc_SycPm*8Q&Y4wxV|N{`F>Q5(LShPymdCmTUMvVn3|6A#;NPNc=NROe300$h z>GCNSREkJa&MI(dERCKyNcs37-ipL<@jU6=Puw; z;3jW>O4*dt&ES>x3f8H0%|Tz;3x?_bLcVgg&wMms7^YAXO1P&>ns-;|{acC4?xU`+ z<-d^TzsJ2lA zDWXi2BO{pUc)M!AJ|B4IdB-{TzIuCdT6msckGlWZ3XSaWzIZzh56ifkKAs@WQ7biI z_wq(E-J&?%tm`fj(Qx97;?#7zw6W_RJ__5P+z-PG7jdgCT#B0iRz0ScaZccUceFh^ z28XU1N2B_QtrE*iO?__IY`(xsWI46EHQ_U50%!2>uzbsp#uy4W?j!TDCT;9YlsUKi zMB~Z?Ce6$vuBNm07b4evDspqwcf{o4OD7gY=W&nO665Fs!9+DVA8cz|H7OMAOSZkM z?*8k95Fr$KnJXBkP@_szV14;)Vr$ z8`K%&z)^@&dm?Pjr2v#AO+DEwvX==q4`YOlSC|j`E9sW1zs3~gqHiM@+*naInv;KV z7O7oqU7C_aKlII1#?7yqb}XS{EMDAgr#DglG&e;Vzx$~s4`A{;kV~G9-4mVNkzKkb z@6z6W;ZYczo4>7ds;iWdZ<-B5#-U@wu5qU*U1PnBcEhUes->&>7c_`rm@`fZotVC< zzG5(NU_dLv{V{-PDlJPoP!T#PBQlmvpl^eHH#8IK7V^lQkrI8p=qYL*?Bx|IU@Te( z&;b+Fl18&LiS7Dk@gF;(J3Z($h{7;e%XP+`$n-N?;9VIzJ1kGOCVEt3Ts93MNLw6Y!*b7p6kI>vpa3&(bP& z3YO#{!L)}rO*J1>j_ir>y~G*gKF8X%`kvY5Nn$;nLr)@wGND?6WPqq`wCx zi^TMW;)SZSFu^qujxW8I33f*x_tAFNOSKae4oK_q$3|#>5I)SE6$e-;GkFR+xx1Mq z2VX7Nl2OWfzzR}#t{w9xcDOyB7h*y?igW{1e;t6=A@v4ZAW1khGCM(%+b235MpSpz zna*{Nb}80oH1bcv!2r&h7q;HyR~=~fG2*Weh>lzGUJL-w;d3SG7GLRY&Nm`K!}8i|1id~ciWTS63yDoTUeopfLZvo176)E}Wr%^g^jaf=vA|V}-(t;+ zZDHwq^s@%7c=4&^pd0i21`%}q0g%4xE3gvCXe62+k6Yf^X-Ri~_Y}-n@Y$)tv8x~!EuFW!LbSmV}a%i7Z;xep8s5A5PyxXvI!?3T9w;-b` zoA=SVPgl6V^!c|^bJf4U6Uy`7-U6gPpF$A2ZNLf9-|_jJHYq_99AB zdY4@712&$j`}Crh^Llx-pJb`>Mo>|?pNKju8VU*vjz;smSPcwZUJhgr3{<{&cw*gM z-WG0eV_JV0=%`*^&$$GJFUQ9d%6v=|`S!0b2%<+6ha-7OLiLRjp4iV0LtC4pP|)F} z?a`d()J~VH?#V-E#RK0;$JWdftA&%!SaF>8;*#P{e~_<@{|L?&udg$hHg!ITbrKdm zm#cxRu?!YFW$-U|2oG*~{xO4zDsC?BC~S3Wu#cIXJ>1kH-aXa#ULh{x z-dtK|sLtg+TjRE2RUe#vv|TL)?CBFS&zwxk(!SU$uU3=$Gj58#A@sT*mPlP!=>;Za zv2VHR^q1q}`r)|jEso74+N9MxHTKRHG7M~}YEs5k52?MCNP9OWqaOdzzIHT@F{5;= z3nqjTPG^`hQ%^iXe8aNLs8>?{(fX*LM{;23gm40r#AWgmts!~d$Ow-6`MrwS((Po% zssT~+nMs%<4A!aW;QOfJnp=;WF@>7!L`9;>9%Ohwqv<3Xl}L^yn*C|WH(U^!`&j74 zgHKSCqPJq2P9Q||SxJxZSqJQDQq=bw#eK{qm&Gk8!TbES&gq!aCkrqU@skpBu+YFc zqI5{)E6JwLn&3&(&}N0fiqC7okU1&?!X{*>>RkYZmjfp{5Z+w6qn`oPF-bNPeC5W%o` z^V^#iohPB$-P#Z=+BOQ+1g=UyLoP1R5_j%^(rnbIFX#KIzxI<-gPgcOyGy)%O?X`uOG#@)wF!e79yXD9=VPD{^qdZD~X!Kn#z8wu| zx=FY_p_f>*#@tiGdORMpGu9-Xv~wwZzNQU4Lq_O_mb%nT3yCs_@EsDCbG#Knl9)@< ztrYV!HhGN^{a#lX-@Jns?zo*+Tb$}{V!QZf9Q_p~%D7BuvC22r&-;_S5lIwUF8x<7 zCAPG*$Ir-L__QBJKMyzTbEUCnQeh$C)3g$gKk1)&2@jQXDH8=89y0)Tp(|@_HcYt$ z)gpm&&(}E|<}0tZ%CN){n}JZ>S~#=~sE&Vy6z1O(i=NZ5kLAz7Q#rz|Wk*FP^%Fgr z?bnw}OdzS-?7w^|sB1G}A8e!%K~CYj6QUuI!4A}dCK0EJ z7!v^!uhnsy|EO%~LCDVH#0!#WgLt_5&2Xu=?LYkcyP^MGp#LrK{Rx5oj}BErFGiYUa;zr{q2v6b+= zA7(qfHhR4rug^z!T)!UA8}fL)j@)juygfv&dv8DEb`%X#zu!6@lIEmk(mTFA5zF-| z4o4f~j$qg>J~VAP74O;D^h{kLN0**)2UFo7O_I=Ij*Iu4k;p5i3qMsKkDRg7Pko|^ zwacp6!D}*i-QR4z8C2Yt+H_#8j^B1GKH98iB%E3_TEAtw=hSwjI8iyA{wQzZI~s<% zO*<&0?QqQ3Q=1y@dk-18uxLsTX%T5Pzg^bYN8>w1TAQD5iad*tdiap({r#?t(k0mB z2r1RDheeJDFrC25LTt_x=?2a>u@%|3Lh4$Q@Q)i7_XmIs(Ky8bT(HV9AL{~oEN+&?%5Lg%@7!(e2iSP29LPUI)4(+?cb`V|L(#CeNpp~VtL3BMq7k)Rh~P73N6%rZrhTOdR*shEE#3jJmV|{DMeu4ou98&{I>}3Q?ylF?(X^bJvU2)+V{rI(? z^2z1%t}HJNBs@>2hq;=in$VFUiDh2CIo1v>P3cpJ!g`KQn{-`&G`H zV^0x6D_+2Zyn>fW&DMByzg)FZw$CZ{6&jQGR%9t-zczPjMdE{HN)JxMM?O_JmB3jH zX6+UM(O>^a;({$#)pplK!`cx^9o+*oTe#^}{XW4R=?Ika`2t}(`TaM;MaZ$o!2Dln zxcm8R-K?aGem==I09C)ShgW7>fM7O%(t5C8mi02P^SS6e%{ z9jc@>`6Nsmmq19ffYZZqp@f=7KAKQE*$hW&t;+DYWM9@;#3oF{EunB}=EHK4o^F$D zjt5T0f#;w!5EpOWi5q<7>>0m7K`uYhsJ@qVs(1VTo#whOJgQ)R2(<5&cxCt8=G1;& z8#xh0$!&YMhP}YKT%X3u83Y01FkM{ac((R+>_c{t_AFT zLRpfDAAS@`sX&}FcX}9(;XrF@54)oI)Vot`=_WDI>!bF3nHJ;J1a2@;j=o;xc@9%4 zqoDkIP9$PXIVMV^sih)c6|Cs0#81ac!*7s)G*2G2Qlh=VP-vvRjX35(MMoY!ICifK zc4olzwZoj0C-TlhpbIi9t43Mr9G|)yQ=LkzRlLB`J`0#fsU z;u8mKP!v;K`~}cz`zKo$f)}T5mmh7+De_qw2Xg^hb|`<;B3R!hyZmCt9*nc;U7>}o zGv<pCoNb3Tcvjm#&(|+n0Lgce2howXBPASW59SIfdRKgNk zP|tm&$e7e=W<3HpIVi_WPB1P(N)Z5=FnL&w41@i&>1O%cFZaBf^rJE|mZKLX&ww$c zbsmrE0*wLlslY&+NSlj(y1SW$?YjN?h*dYG-?ewVhYjE?G&`$4b_N>miQp)SSlX>( zN*2;~(g61xpMqN}+*;f=n};eJ_St>P3-T#rE8WG-xr9JYB=16RizKXK*PTs$*j-~9 zD|uf>Z;I=;!orQO2P+fg%v*vp(q+*@G`zZ1y$@|_*1+fT0FXRn*jB25mHt)K@fwhSxFXy6BAy@HeeOun z@d(c^w`J-u=Imc5&Sh*r+?L+~-=7TVb{|Fe+<)Pq|8*B8?f>m={EHq?ZJ9qR)FTs@ z!>EN|f-08_5n2;86`~S3eVn-ip|rxut{=Qq+td()Bh5|bB)*r%y~pgdSbMi{S48u? zwQ_rHK3^STcw3mpk5kWgk z)66*9nGY2!iE<~qSB^O#Ug6qvW#eyUKHI+pT*a+~*oCGPW)gizF=8Q5_mY!q&10O( zJ#VDqSRUtfR7M-bEPh;)zp*hiRdj`PhG$P+P|`UU*OT?Ysd`>4=nkxR+bELvJSk}= zGf)jnJzD`0=m>(~bvg>z87==rOFu&t8viuaUGx&uoj?0(0=yZOUGNz^lcR{G4)&$D|BnYMmUDguoor1 zMvdD)a;wX11TZX&YxOe^2|b;G6$KTU)<+nte6Y!v=)$sg-g-#U zIf#IFYhu+J6)h16&c_rF!T)qey`IlMpnQ}Z6nJRZ59`y9L0^w-7hk5%4J_b0o^hR} zN-73Z%CNP;*Y+K}@RKBheYleT81-G8QiSWkAV2b8N5Rs_g;@(w51H>WNpuk%*wX|m z45noMHOPJn#vIHe4m1{ftXDqrChBCiJEgF<#Zj?Oy!1ZSVfK)u2+QqWuW($iF(Z_w z%O3kTmgosEOo_Zz3Ak3eHYMcXP|qwcyXbCA%pbLcq zebrkNDu0V6zjD6GO(_j{GP_s$>W`NfDJzx?82N!{RlI`ut4|;!3 zE574Hd*NkGQ?KjaycM#T8#0*>HU5iWf4gl+^!Ls3-+|n}HxK>wJAVUne?pM+{&zwC zx16NkQR$IM>S4qm4Mo}JO85_C^1Z~{anLCZs)114;bd(d9YyTKA;JAtVP{ceWf2e7 zu3j&j_uJbK57(93+sawz+VIa0Z_}5T;N!HMJl8LGLPAoH^Yh=N`ItBi=b!Er^NZ9^ z+X#vBEkyTb=4A^T)6Oi4HDjI1qkG0y_9&GUoEpAMaz(EhH(E;0JBe1ZC)F@3l_b== z)#8pwA&<{G=psrE9Y;((S{;`qIwqVk^iYL=H0;c^gx)osSE?aXQMQo|%g>@>6ER)e zbdX-zE1DfGO`;rDpEqY|{V)^O9IjH7#cpYs6lhkx32$+9B6)$~Rg|?QI}d3-V5xQ;`etWky(wz=bt$J>4CBY6dd}3< zMA9@YtVMu+M#8&yF4|9L+DW07pE<`a5WM4oYLHFZu4vuud z_+km4fuoQbcjh!0OiV;sJ5=YGABT0UCVb!#^AkfbnHkiDkh$bHC_i{Fa-B~PPNl0IV08!yhk#toc>MJy0EKIPL%VX zsEQDo1`Ellhe6(R8F?{)?yagrtbuW-EF2}BzD33jY$No6^!<$Zj5#xDC?=`{r2Prh|;RYJo&lE-pR+mpu*R3-tpJsL#Vo4vif5Eckh19F=toQDhJ?1Fo3PckJkTC@D+3S62lAIX zAII*Qg(ef!jU2WT+5x3?tA|`2B?W97(>xzIQI10ZE;o2K;;=LwudDlvKIkU1%fBe4 zFB5tx`SHPr94kl5%N8xw4Ojcnp95{D(aE03@l`)hg4L%t5=@`w@SCb3vqX*!Bd&8J z&g4K1AeTgd?W#82`%=yVIJ8xTFgLzV^t1nHatGiqO@72{I-&M=p)USE0QJ9xygwP% zZ9eX9|81=Q_8H`lRl9uj{fAk6V0~af5dv(ol+_-Yf)z#9?a@oMa16A%Nkzs1 z$&rF#%UkI6;uUv(;P!HUeSW~Y)%(qEabTQB3-_b!CGnoN)%#saDCy6v+9|fj4Mh5A!}?)7G&&W^Xt)6j4=19hv!AX9)`;KsLYJU+pMCb z5|Kw5v%Nzv=^aWZQ&Wk0L)&M~`CavcI9bB7?&B;*M_YzGGoyjtq!GK~2oRGZHS772 zjHZ!PGZ!MhdwSJn7#Ig^?&9?Z*ejOV&C`!? zcpx*P$=hUMk0`uiizHy+ye!#F3{!^T(L>S3+I+iY4j_Gs@5-a$05T~X zwOp|GoNiYOT&OSY~zA%nVRTfL$m%69d{YhqkB6^3^rO+=g>OA-0}z7+3^FTL_+4DGo%TD zoPJ|Ff;PVwI!8dk23mw-U#bIk;0lg|Dobai?X`*IQxw?F0BXXH?&_wGtB5E~LTf6F zDbCV#*8Y%#oKp=rVxV_qN}n2iehBAcY;Ru;UU+M^{h;V$YvgHmv`Rx?v-V*@rM@b4 zl;u`LwD>*_cz+l+J1wjp_$BGFEmC?ASacKqL0f^2rxbHMd?oXJd{uwRbq~GHw?pI7 z^1P&J!Q+YNn;Lx`l-LDs%nUrwdH7aA*{q;$sx!LnYr5x5qTWu~=&A=4+Y)d*B{3UA zo+1?6-LGM1HUp!3rkJTp`=a)(W zvi~jW{mIDw&pI!ElkF$sT1NYY2kw)n&HSqoP<}=z z$ZIAdq9Yc6d;`F%Tg%$p%dy*Y;{1JOa=YjIq1&_nJZ-Dj-t98#qWh`$tHu>o$j;E} z?t1%~W|_I8b8nR95r_TUYe}7?0{eJH#aGYMXmREGv|y24HW4{vF4{%o0%4rQGAX8} z?xbd{hBJxekXC*rw`aCQHDPo+*E06RajwD`Da`cAf*768};FZebyV{qQWiNG6v$dL!Hp{xY z7K)a-n*wiYRThw9$g#krnPuFs&EidE7UGN4XNf!broGkHOsHEX)d!s)Iyx1DU#;&QDSLL^!fEqoYt7=3)KPqc#x7_cW8W7BvF)bz?YZ$`w^Yza`GIf3`Q&)vQ$TH6FSt3K`B6Tdz};yy?jy6Ph??*ZcpcV?#Q68gcfl`!{5lb!X#fZs*@{Qp0!B?zYOF$|hkzmrJOb*$c?9()~ zt&GneKs}~vXv67@#j{aVwghD+I3$V#wy{%#ixAMk;CE+2m35g@q7VCnwDiFPj7WW#=)!!Es}j%@SK#Ne-hS(p zxYj^@(>D^_hr9wzIP5&45FA*$(|XclNm8%yL3Tt(=Lqt;6m}bU`C-f`*H0)s^mDRw z+Cxq84tG6JY=KT_+JYtA4Bts&8s$mBc7oysXl<=Q#`CFK*KfRFu3JBh7%cqd^noE= z6+H_?;NUbIrTAj&7s}4qPcm-_krGJr>6g$w*NSUR?Q+4gixD83@#1^oS$M{1@nntR zc$Zi>hU35_MSf~uCH)k}UwQF70}>>_&0XmtPrAZESK?vW(y@~wQFY_VIZV;0Sh?~3=KEF zBp-aBecP>L?fvQ5?LBh;c)8$Q+q-$~edjT8A2n;eV{py<{n&m831Mi=bJ*K!xh2Fr z)1JWTL~cD5>Av*CR%csmk^1PX@X%C@{yCL3Un1#c(mb@VreQ>nv_)< z7i4>U=Lk!EG;O#b_eYVI(5Tb`V!rV40Ki3Y7O9tWf@IhLH#`I9(6q7b5g?JmHd8LE z<(7JPs|Bt2v=jj!6aRLweX|?RCkNRR@~v=2(WZu8)WS#r{JkP7V=*~+K@*>943nTp zyT9=)N@vwH6~=f5P4znmySYFLgO+= zkZuLNK}f(V)YfQ-94%LPdo;sOJtEHaK8UU_FG@|6zF-UxDTP~W5F{V&x`Kik?58|B ziali)Rv8kgq-ZIyv>i)9EDDdb`Dc|bvw> zY#YNWEnKiFIq8)E@ZqyimEb^MB7EVv5EaFEKKnQUX&vymcHP@s3uMFUykPkcy|fa$ zXJ88T9L6JIe*L7z8$tgiEv~i%1?uz~8E2)?Zl>4l^pNT&N>1c2%;|a1MT%>lTYD#LS8= zRp#>ay#f^yxWl9l?%zlFMF)Ir9gIzHEMX_4S21*KK<~uQM05&@;+a5DIu#!?q9Zpm zV#A5l!i~Ae#(=h)z_IXWYVhno&vG^Q^4(hwXE&rY^fqgs5m%ZoI$N;7c;h(m5*-*LOKLqEcV&#SLB8$+V!Jv? z84COVxO=Opx*9E8mk`|D-QC^Y-QC^YHE3`N5FkKsclY4#?(Xgmcje!8>zq@SeXH)N zR@HXfuk&fP_3+KH`skzgX{oe!$V_*i{&a_me(cG>^_}Oov3Ca~n}Bj4P0x(sJagM- zhd%b5eXX_tf3yH3!&M8prAd}0(bEsY$?~L*^+W$U@WifWhk)ltVDc~w*nuwR*ntW3 z125y0O~Tq1O!ZhT{tkh{=)0=1bOk;kA(GS0aB$WKpuf0@xg&E}_S0+{|A zX8!{N`yYt+4@UL>+Q9zrat_S?oGToXBppKnSd{`?Fo3`=vOV`ja0B*2Ad-2Az~@Jw zc+I8h@B&K8xw#67u(OZffn7Tu-0SbpFCH(^2P+Fb>m6?{ZEr(2)Bu6K(_b-Ox#I=r z8APR2+N^IvUlh$zn>mq^azv;EaCGDvQF^2@l9pt;@WgXk#uyu=Gqxu!-gf8ci?-{ zn`A$OlHA_n8(^yiyXZ1@gw*izWBOK}@wp>+l{pKJyj5g!dpBlfiddZ(oD#fZsiz;OCk#aN!BCf`#gIAamj z+?h-Mz}ya=bYX5L6|u=|7+tnkn20T5tm<{_0D6=>{0WqDkSGLp>v!~{xra{Qfrc^HCT!m-d{0g^?O}%)2rT81`I-~bo^~N{N)f`Hi0acP0`w=nm zrL1M4f_{P{9H1jR3_*T^q>C7zClOzx`3R;u#IKU^qGads9)WZXNP>3zukfNyvVnxV z#71yi97=gT(?4pPV^ft@1}c8t#X2*$Wv?$+!%7CS3TZB$$`xurhXPzCmd1@4pH1z` zU5$+|H>Z>hNCF^GzWz|>e_n~%TRhN%q5*21FvhV1qqYr!Ql14j7PTJ47}@Z{eda(| z*kYz@Z;aSje9X>PUHpxmg>M}03kv!;R4+pLgFApvbjDF^mbV! zIUd8-64hE~5-2FX03`vPd~qOHiPYLdrtw*G!i!orI9ndtrx%2-2oVV6kcAxF_z@)7qn0K74ZUX z>VTo6>qdbzl&JOdkHQ^21JLiR46SqC}6)SOs3Gd<;(or7oseKk-bc2meLa+-@hfg z7@)@m>;KP8>wl!)KNZ*i7<%x>SzX$WRuVCEV6IfaDBO-R6B7~IV7?THq#q)%&8Nem zSxe}9Dc^i`%#Mkf=xgOI{>LRCi1GPxp|dg;kOpu!V2a=Qe)RlEe$jdT4t>%2kwet@ zx^Obx_|xloQ04V0OhU0SEmdZVT&~H6x1yzQ&P7gIQoVP{OV14uF&DLq&8b&^=iIzX zoL}ynb6a$n@93=^JUSX2yym9$>we~e zs-mS~{)EVZ+TG7usX#5?)S`K{fC)Jv7=LxhyxM`IGshttJS~a9fWRbq;n_rUwVO(3 z4szXp<%Dmc-fxN#{RT_SbJtStjP-Md+gT**Yn^2`8PKv^I&O0s@hoq_`1XXkTdd`G z96Ye6Bq7NDa_*#YCxo7SJ$8gTFlpTD@rx`9^qV6GjyMRhAFC}>F*)BAzI|s-&YTeO z%Pmr3m?Zt2+0hgfcW)vob)n@ys`2rF`PX5qw#Q?ipxjh0w zZRLh95=E>uQ<~Y+%4;_?;sx9E$?M9$wn+6aPQ*hlP9~r?vCp-!w_qo>GuuKACSiX{ z5cx8)$eE_0QDwzp-go^eB{tD(i^So8NWz}^(nE>Z;h{kERA2bXN0 z;bhB4@gq;IJ;cEHD&R&q3Bh=)$~B@=i`+cxvpkkuTfn6ov}+e0xzv1&Np1(yCOw{V zDulJA&xGmusqbVcNZJQK@l*OLb_Pz}&nG3PNlY=yuv}ZnI_WhFC!^+-T?r$|Nk;lA z%XYsA0R>y>h3SRL4~Gzv2B7c4rEg{McAr-<4!=izzxUu&`((rv{MFI=K3%{<4pMgM znCtcC^?4GB?li5I=ZDbl!Uix;BIqv!hrapr*0 zTGmm1)__xUd@IPa614aP2ZP)AvKK30bGlI$7Qp(dH;{U_JJ^q#wkJhKi;6k?d4!Cn ziE{^66hCS1!i&tz`Ys|}|JkVYq~wvmoG=Tl@`O#_D7O!GqjG}Ms}zdx$v zaq?Pwqm86C662lgE@edlF6mNpPsPE5p?TfYvbDKNQm8C1ToRYJxmA5{!YE%umXER_ zUaOJjNcA1f-W1J_eCtWI4_8SGjTCoxY!rv@(>R^Jrq&B?4&TfBaMDV0{(AU!-V&62 zjLglMAF)vy46JVZh}+|NYeivU8BUS4CQU5%(YpCpm#{L5fITi4H8pj(5SPLULmtrH z;Q2ZOA1N;~dI@?gyRpF@YgqL2X4ER_WAAXFU6(~H_C~RGCAXoNtu?3P@!e*wA2HVX ztO(~`nFvdBWGf2r<$B9=L*J(8LKklrgvE)09C^|Le!|x~t224@5KT~$a(2bvMi_80 z>wzGe7nS$IZ{6`DoNcv1holT?37lFBabqCZCfmuKH=MnQ1&e=^+zjy7+Pu%l<)?7R z%A>qJ7`y;hT!DV@$i1(g*!_TZyu>>{;Xu16|CychO4pZ8O8&S2^A%V2l{ROBSIdE) z=84zv2U4R5PAbQH2!x*@WT?1%+pN<9>U}>e`b3FqtKBojoKm$}{H@a(=8?2%vE4~G z-?vrZ-G)c(DlS;(`$iB??b%WIliJHRaeCeL`IAJZCni|*DXwF@_8(>@xHP0owG6Z?5U)3aVLd$<2h1AH1vxLhzl@a8-a7r*MOAeNPJR|4N&O&E&I$Ux}SxMP)Ho-{;9uf~OWH zokg9X5_&sPU2Tbya(~!^q<_cNLF7M%Ykm_nbaetA4YLT{-+!&+MY$u8bP{4JmteVHfQ{?nYEG!jAcJ22ffQ^j-WYfI|lH<&_EY2 z-*L~;KgU>h>wv1Ww`C+tC(omh(`4KK8p0_w$L~aK`ss+Sk0Pc)4G7#$wM#S~~ zcZzcpJBc4!Hk2^k~VX>KO5-nkd}q@c1`3zL)#;df#8NX`U}{67MAJh463l6}D19 zWbV@*8?;MW((EjwbST}ufA{zXtPF7a36=* z%Sn;99votUr~0Ak@!yXV1u_Hzc99nf`c)ercJc@PtvG}(%P<~**h5)qiFpzVm8BYZ zb_E-&v`^Wp@MPQQ7HI$OrQ^<|ZjPa_O} zp)L{uuhc#kIU4+tq*iDAMnco%C@oBSliuewPfghS?F&6}_;a&y751u=?k}yVecg@A zZW47(r&{D%^u#N_Q9n{h#>p1tsD*0!w5?^R==me?IW1m_&TOR_J2v-~!EZNg@T=y& z&?T|(&jIB_FL+u-E*}gO&WIl%FAk}3$>XJqpa1bCW5HfuW%rxE5AHKmky+uXRws{0M3bd^ zDfmV`jq&!$V6Dl(xNd#9Pox|V9JjjTU~=eQ0!*q0p0qqF_02H^Bzd24)=E=uL&Fl1 zUqx+;bi_C%{45bsb!Z8R3u#0-0|l0R zo)lGAjJ$TJbeZ~qr`|sgM!aZ<57ggVQ9PiNx0|ep54{H+nMeX1NzyGBy*Ot}fUwQ( zMa@>~Fpz-(y(?HspWiJH=9p{LBEpQ-P4Fv2)?6-lIb>gG;Gmii@Q#5aMQWZeoT-O` zQ!COp?T5_WCC5#W1o7|6@qx&6%Z`}7ZQAxys;3tYL&&UuNh*{^_}O*pH!U484aBL7 zQC8jXQk6_9U-!4s=ZSW z9wQM2*7tVWulBX8Ws}twGL214pSrUH`+WW9tgs-?F81CI1Tz9AfM!k*?(q( z4WTnGGH}UPDuBMTQt8HAkyK$!*Nw&^DDI7bFW}Lu5Q7~d)S`$}V26Se+NSR_%4h(y z@};-sFB==`8au1c1UJWj%kFlEJ@Ddr&0|J6&+Qvsy>L)LXK;jnW+<07`$k!UR7t>^ zY+c!F0q3w2AjKAW$4KU{$?ew~9hjv-;Faz7O$_#_Ev?vu>hhv*jYLe8plej!7%A#& z+k|>kd1@7GyN87yX(04;5*tc%5b;;*fQPTWitCx?W`b?xSi&yTJ+#X++Q2h(Cfd0v z7N^_YuZ$fCPwG)~K#39RqoWm46~H1SkOHOaq-OuF1#yAv2oSk3kh&-xBvXW_@wVyslm zRfoXP%jzesYF;crY}haroWO!+h#8ic-Kz)AgyV!p6+e3MiJBrU`?<*bqBg%)Gf;M_ z1QW2vCB6K1F#!UB*y`{DG5f&!VTTaR--XwYsh<;>o@aH+4h6jf&Z zI%gChnWdL2jQif;t&%1XprhCnx zQH3ZgPvJd}&C(nnBp}cP)A!8cd!A3ZI7dq*MeN5?pr#5KV?y7_JwGJ7Qab+%29V%i zF8ZCs_#140e^n~{|KVEySI+&v9Y%khA^q#qze~S=FtR5DegL-r-(>$!Uy&y3+Tr}J zzZd|7r4I;verNX#X!{+Oe(+1;=gz@N2IeO*6k==XZYS@wG9%Px{*T+j-;s>^{`eQ2 zH#c`@RS%V&I2RipfJny9tDC<90$KsbM*{UNCTg$GWHsUGZjD~o_93e09yqRasXx-{ z`;%i2V-5_>Y2Y+1v_e#dV-^5A(by81#=N4TE4Bj+&UuUUkjoFQQs-n#kf#D)%cX4J znDBhbK`Qv09@mV%K-3KC;vD`S(U_BZBgG`zc89$sPCQ=CIYvI`t?QYLT_iK6V=Hz& z4-M8Wvy%{w*X|P&8twTSdu1madnq~g2_4xf<*5bDXypY7t%qSr+lsr|y!__$prO66 z=FDQsAHlQ{@%UT7$@CR7Elstxk{V*!B@PGlZE|m*KN6Il!Hzq2>L(TeRA=otJ<9z- zSWQCCG;7JKepyHwaooRRT#@TsU|M+6B*fqeIkfF;p=(=p!h`D>1LtUU;`RW*y8F3M z*t%^v^BdJhjO+NdlhgfmOulc|HM3RzONpLK$oiUXU1B1mVnT2(RzHYpHb@$8u4W_B z_2{YQp#UZK6d&QbhtekwHIt)i1f@7`HOiVF4frk8gJVI*>Zu9|vWYrunxt6hG{a$= zYjm}}K$+?|rn_=MaFH>h<1?Z^P%nuoY8}KK`=(*5^^>MAvGL^LRtKilgKfX=AwvO}SDybk3y!KYHwJCh{P@bE}$f%uv?Uc$=x5 z+?fWE7udupbcnaR6*@~#`f6^Ow*sOB#{LuxVmkO!7t_YjU&r3 zKsscb4BT1Yc+G->m)^TzZ8#eTD8p0MJv=s(tFT|rabbbwYS@@gQ`;*uj6ktv{8;Dv zYPmHqE#&W+(i2W{fO3g&UWYoWeYa~S4lqt?u-dmt+RmSwn0fW^M6*sl#~MHu+0hB- z&`m&j$PU`Nl1XhGB-Uj35s=>Rkd9WIHPOrJbE&(1Kaj(awvq>3)DCW0P4#foc-s^Bw=}Z=B<04IBV) zp4EBt{_J>ou%I6^VgGs^o%K5}J+jQT!oMBP6N+f5+3l$k-x}35=^PFEJ;}O%_HD3s zJ|?5p%6dtU>5k*}c3b)wDXoKPe)eXN!?`l9yQ0f?y?1Y{q#>JTu`Jj>p%Q zUp{&wnz^S4-zc{8D%I1yW}8R8w@45J(;q=6XUMRRQnhM9o!eoZ1sBtqi{Y+M$=Dn@ zeFIwZmfrP4k-JgovrctTh_N65am7wBwF+-~27$Q=nsTbUQ485v+uJjMt}Y$pNTndb zTwbao_Up>=1>jh3=0ITUOb zX1}zARgTB_4hZJkI%95X_yC+m0Ch8|KFNjZ*sZbT zK!{nUc!ThH1ut9J>`sr|_oW&e0ki4t&)_S=yAskyJmHv0n@dE5oCeTJzHsZ0&6ZR) zPN3PH119oyiH+C?d$Yh(%%=Stw{exFw%M3|U6@L1hnpafhUdiYx*Izn*o3A*ST)SG zXLgV}vg?em$4BaFI$&f63THTDLp$oea6*Tl=!~79k!MxyaRPGA_U@*-M}FDoBKXZe z%fn`h>UeaRwW3(>f#96SGID3-@tGMzCvSk6$>Aq!2Kg~dr3aQumz{wp75ePa?;o+xy3dnoGrKF_jn>w+ujf&1Ay5ojt zR%0QXS=yv`8>^*Gpa^WHb72nTz2ob5g0ZFqUd3`Mf5rPj@?#7w4~JNbFHX`{0&$(q z-;g1v2`_GjJW)awX~bMW9(SRZ!MyQjr7JAczYraA??Tr6KP38pc|!jK_x>4}{`YQW z|HyP*I~!5Jj1FHau#LDk$bXil2V{Q=Op-Z;N-=V9b1OsAdl*5INRi2BtKO`WndSF7 zQ!#OJQ`uQLvEljl?6`DL$*-Ta@pu4eklwi)fTwaA>Fl8M1y!k4b}QHC`#-do;nx49 zz0kG(FYQIou+gJ5&HzVPT( zKUlJ#cF)f}Cn;3sph1w`kL8&P^56`)pD`ymv+}Lh>obfpeN~`VJ_$<`3Q@?|A8=}7 zLb=L@$ZI$eBL?*Y96fBs6+DCJnzmY^tt{JmCSj=bQYud$RYp$al0Mfzx%u~2R3GT% z!L8AiD9=8R45@DEEzN1&o-c{rrt+kuU^bv{eo#y2I=s2k`cY;MrEAQh*nM>RIkaBQ zt2|RYhoihI=NE2~^Nozc@`^*Y!UeIfjpZR!;YTVGEZ(_}p?Htq`W3b?NvW<=x26|T&a)a>UR^aiVY|Ws=2*{fGgEgj&3b6 z45z>wu`85`!A!^Z8zT%$)clM1GFtAzm)4dKsI(K)a!Mm(XZ_V|L6kXfxYJV|ol0%r zj~BM0?_g$=9qVYM1(cVY5cNgR4!w!n{9v1w(~SrQ`@VW!8=3@AYUG$@3-j6wJOzE1 z%VISsZiSB9aitMj;GIhpXRyyg1nrs9womPI@oTwCu3s+`7!=)O)>BJ(1twXPCk@t#>vmlvpRg%0O2R{G)Waj7ag?zS*@aS1u~wH#60`~8mm}px zUVA7k63~}CjF#%Mg**a1IpeVioZ~V+|694D@GDHXLsgHE@Bsz6Rg zibDt@xiX|z{!G!vJ(1l++@EyYxy1Ytr`dmK?vWN?>V}woTO$UTHA`M8X&$TV{1xHrF zz1C2}-$NJg6~OcvC5g$F$rGK@1_d$E97nRpNVQV~fbxQ|<((`eM^%>pVjo2vu>+lo|<8# zcnSWF|F@G;=Q=8Wi~m-r|2^>i148}(Mt1qb=jxA0m$f1VoRBW?{?28bRoU~$`_1C= zVgLGiWm@T4anTX;hH@VhF=yG?QJyqwsy?T7z%AQdXea)od6}E5mb88$vjyKt>pE`H z4N`l{`q(kpX|iOVqITDVcm3IBE9O*}sNvC_xAepXRaIYi#Jv!2+Wf5DcHqQA-&JFT z^Fnsb{rb|pscGj~O1dRs6`hWMM7w;Mm?=3$r|DJ&mWwrhPP=i{V~a3XR`fc=<0wS^ zH#cK&9m)UFM>Ofd%_{#W;~$)FZtKn5Z$dYhXwjPS4M#7IG;}NH%hf^&m15 z7=0@MQD5!Ld^Pf9mS`{~xwki#zDM9zkQk6odCUuey7hfomiLF7nHn za9}uBl=55H%y1PFk4vOg29wG0VCO-U&TNs#2#J8Sg8k+URzdf4vc8@71gIwev^xCa`;j@j6h2uJ8Fnu8`rTMODz z>=yh-bvY4fKZk|0#h1_NO(8se8Yi4h=&Ye)z}ncxZ#ap3Q*!GK29L#zUfQ>@(}#q5 z>csjRuiJT6YOGYikcM`m5(G~=v7I{D%uvisfkz!$!0LkB#Ii`RG0FO1=gz3jxRSG* zIPSi1L?#$&G&+p&bLtsIBmxgrsXaIOE>AdFm3NiPIQ?})5kF|-%aV{Cj9&mFdN7Y! z5Qtb{o(oOoH3w)slE&puE%&RPty$wFcFnAM4(}2-cL8!7D{pJitbnW3b}mnz zM_|v-+3Tut-Bq2U>1peVy=+X7V{{ID#jUkiRwjkLt&oJ z{dG1Q%NEP}l;&AGW!y?0xO7t|IIX63L<8uu@b7n#b&yZ?Ah|1SzJf1ut!2hablGxP6U7)AfvVk64`quA)QM2o== z4c-N|d|ZZ7D0}evsgVEdk%td(H~RRRF|iQa!`J!ln$l~Wc%Hx$r{thU0vnHN%Q#FfGk%Xc;XvkrTW7cFU5%!s zhI)YO`VFTkIpd;F$fD*6 z7-z6%PVh96f*~Z;7~);tMN`LZwkWE6d>FOu3egyO#L)^kpU|~h7Pd&daei9ZC|b6s zMK!XDrRHR$kelU%tOoU26&!7`Lcjq_W9x%u{U`a-o@1eYj+uB9AC>l|(v#QJI z844&3zv|-+V;|1B^G7&V+8#Fho!w8R6NEuP8Ec&fUQ|fFl9^yP6qT!gdB8ZqV)d#= zNbNZ8sc0s+D%v&cwZ`X}mgv)<(gq0WsFzL>AmQcb`;T*JCN(9Ewa$?%Xt$^b03{vt zmfSET^Wp+TIRSjSa-v+56;aL`vWQRpkgy2f2?DJKN$Nke<}1_32sv@CrzoDgcX}S|EU9X z;9jy41jdt*A-^WDHZig=mS%9iKpQnDn=FtD8Mnvvu;6y{- zpuFtc`uk1#AX!CeNpeU?q2yBU+n}?wxcP;yTD2-UURY)atFUkC!n%_6wx>l_@f3(t zqhCN;@q^SuMzg+oO2$e{gX!4aSbeZaPuG4+u6lXT>Vy*#kclnBfVpe@j-Tzu z&uQ)fKr5mJfg6c?gX@Ot5+sN2c8QL)^iE7q&p5#PrYgDSs#uws5x*t`EMdjDj>aiV zYg8p&xZvwH1Q}##+6w5+B_pvEfMz}$ZJruZHGqoI8|+YDFj=cN-ith_mG}-dS#P7< z)eHM7$w|rSqUhSb&3RzxSBx6H^juuft10Tt{(BmU`7q6_gy#OsG?->#gCg=z#x_T`sibvx-?wOyqS^)=I_qvkCa zb6XUl3q9LlZ7sTd?ZOElH zVjz>LCz6CN7T|U>i%`>IjDE9263(f@)QDndwGjeOk3Szgwv>$GVpx2lr-}}e zK9OU#+lN9*BaD;|Eedo|*Hku@rXG|pqkiPz?~`E;q%-d5kgI*+KxXCL`^nWo$(M?Y zJ%O8)rv#A_hB)s**N+9R4&0Ii_jtg%WPJ8Wd%#7G7LGS2;2%g>Iosbv*AcwHuu&8) zDTpt;v0cbdoRU5yQ+Eh^$EoKuklU+1zj=0M^I?~v64dmr>|Q@k}R66i}Iht%nn zNas%7h#45s(bD1mwm5$!AfXZU^GbII7hNsxM@`~3k;FvRjr1|IO`HIA915iJt+7&6 zL%b&1nnnV>#SHgtP*b&cfiV7sX(58${pSD{=W=uRD(0%n{(VJ;=*}HiIycOSZb=I+ zHD}Vtw*EHpXuUJMT3jEdFAnn}FxfA;c=O2A0l6up={(e%P7-3Y{d4*UpBGIEnFAFW zlAr3LcpCu4IIINOWCi3>kYL+OB_O z&v|J=d0?pBa%pJ~6Rm!yH#3rcFPK{(NPliD;%^0Joia=R!1s8tJ?yI}y7H;l9Lc=o zxXR?RtQ%{w%1EyOkv2PL(8m0nyBIAYf&^P@P+aDB8>CZY75-v6%% zFL@8IK$HJaZ}~65{Ex`{r-1o?+JBxr7C|Ep7qW0v$S^wX@-u5v9*~v(Kx+mtFWNj` zy%pD7cW>@*TSer|#uH}b=H@<6Omwc?dHTLTE!;ivuW#_ty}aI!+&zKozi-}j0&p$~ zNMqbMnf~2qpn1_pIN@B@Zj#l~rq*oH7n8g?Q2fg(KWj!R5Eb_t zmCk9ka#>UrP=gUM*G20~RI8M8*1tExD{GoQluhQn6B0IDyH=(bexbFqjQz#No;Guu zm~0^|VP=fDWMuV>XVpPcV2)Dx+-@ypXt<%ad}Rltkba}V#Nv2!pX4ak;nRpDavHmP z1A%9uVo?cv>2DETsUUBfUEzT{(;4r+i$IZK=0fWMt0kC<*e%1isoPV|EmTPNh3`Re zPPCj-WhG864OuBbm~-rtrLq9&1T<=hU7+XN!*31UcArf6$Cmq(+Z@;4k-^#ZdcJSZ zbx2-!drfKm;aY2SL(FvdPjK1_TL!TiHmRRW2Nt`{v0%ruAjrc=K%GL25hI(CxKLB2 zm^fOEx@%m;Q~n&ftqM2cFLa4GQwrU_5@ezeu#wk<9?Pa^2*-{ChH2)F*}_zjHl8gK zwHb#?Qq&&KqLzn0X^^Hb8slt954=JvU^J$JeW*4%_DCY2_hr>^u@nMOMQEOS>{QR$ z%noU(G}%m^2R|5aMkyGHByhg_!eG@0%3H#q##E;|N3-KVD;Q~yNxAvTfyCGZd?t{G624ZvwNDK=)-Uzw8Obo`{An~ z{?WA?$q5nW)d6BbQTWvO3;TMvbQ_i-+r>7QGlg%b0Oz8URhLSMy)Ztw1a71$gdV^7 zbI1*hoH>*kG+uhT9;AwcYSsn^ixz|6+~UJ$gxG~@WTdcurk-;SpHKEe8hSO}cDk>( z?7w|3=-{mc|LxQHKdapG?@p%vzT9GE`rEZQQAQLuuojS~t&&!1(t zVGY4Zc8?M3>er%DLbV2{HBzp8IC%qXL?1Sup5EP#ULN!-9`IkUf;N7;78^-_Z$vBZ zsLD`Lr*Z{BP1E)xRjS2y z*{yG0C#^}$H48C14ZEI|eYhj0=4H#aW`3y~s?BQYO=(5P^*x-{-c1^!Rxjqhj{Q%= z89`JFN0ASnD;4+QFjvzvDQjSDq?;*ViF_|1VR`t#qf{d*A|>uBa_ zY2MT2srQlCbiwwUZpooqvXJMY+JU3(s&wT|b4;8PO_qJnCG^WoF;}Qz-0hJMmv*WM zu%*iEm*8i?y+(E}x)WZbZ&jTFiMGY`Wsa3=M^T@)q4_ETk6-D11a+6rollhLP{N%r zfaMi(X4**!Ia+n|>7IYmR#u#;tlfPy?m4p=QBZpbySr_kB)J!cOj+m8jjI;Yw#I+M zPWb%#WyB+93L^z2h^i^MJ(N-LlPB}(`Q8+Lh&7}NnlHq6XOWpfEhsSScgz+#k?;cI zVPEd$k7-?q?X(Y3@7>vgar31fOBLRSab zuqfNmuv8R(f)Gq6=(g?@7%WcVMC_i{=!1u4Y{=O=v)l@@YoIj5Dg3i2TXMKygE%3~ zTqKhy5!^e2$h)iUBSSrPJ~W5{O=OA%Xzp|y*TqjT9Rf%!DeA zGuR92MW?uNNhwF`JkN#xL$wWH~sEWaL&C(*K)+&aig4vxlN3 zqPf~a4!nT8JSunjV#Cx8d%;ud?iRs8QmeqBlicn$AmTZ`j;+L-1*!ZXwF{3>7Bq4_ z_;G``qYpO(WqdT6kjxC4a)PE$%PrP4mDA^W7OIX!vvEF&kn=ZqZ_>Um9QQpAOG6|q++NFoZ=w!ttF>+l${ zzPzR04F)G|M~=S|2F!5|&ZcirG-nS!T_+6fxNhq~^2REM(bEi1@7VUtf5O`M+e&oh z#^QB!ZWXUwuV z%DviPS6Y$lN4ZD4pt7c#Q2bIG<8}8YzGm1~<}TjcE3d4luBnRC%6+{j7K@2ej>Nt9 zRl8xzu-_)lUt&Wy7SZ|DMsBesJ8juqUPYKvZ0FMg7CdLgCC|>6%hi}&Cs?^HB%ZEFP zN>g?)%K+Mg+-)zc8)hxbPTi;D#n#;R@nZEM&I^a>wfKIjn<@x|(`!RqhQ=nCLJMTz zE(i+*8Nh%4lj6_qa*{~jcgRbC}TmTJ84Z+U`T*{Pi%>mkuge9&KJZ&20k&!>}gEC zGJCtdw+=?57B2 zL%S+{v^Y%H&QiE(hESFyE0s8neQ=1i0@u-S!CDaNm<0mf6>$ovUyfLJqc6Xt!L>fY0v@Hz{F7?V_UlX=g=Rwhm~ zK(Kuteq8GV0w({b+c54@=*GMO^gy<^N9+dNwYz2YrDz)nZ`W3+-o%Y}Q9#8PlZyKo z4ApVj#B<{n`8GgW5J@)lG~YPb zMI%CyL0@}vU!UTIBIVz(aEsory&u?SHYSb=nPf;$OlOe7nPD64`SH=a5PEsX}dMLu~oK{>!wG*n&>(8K0*7L8dhrVGKaAr}~=wF2n`HX1@?QTgM+`F%$ z2b-uYLTBcA+9zaQ5Ip;rYrugowSHW@gZ-Y&Wg+YW4FMeg4YI%QK>rVlqyJ*vztkH2 zr)c*NNbx@xNBa4fus4;`>FmuiqBM^u16eEY zbBPXKzdTKzsBgvf+}5~lq($wz`Y{x{WMu{w74JeaO+)2k(%vm;7GWCeLu`kzuJs0> zkM2(6K*dtEZav&4wMI=$(gsrA^EfS+MK9M|K$l&~i}o4V=rI!(GG#9US0I)bj*%** z4>%+1K04X*Z94Gl{h8(tP=xPOuhShDX!y+&84-{s>*dYaz+)W*P@*+0s2m>Bt1odgPswU%vvbaEhMKmZ zHPY@gwmI0rY336j;wUbMkAZl=a&27uv#9PzVhl;)wRR`ihz&<+*>CXoYGtM`hrL5~&qXZwe#e4)*4S*|+VSi3_%55Mcg(T5W=^yF%n zQ4kWzi>6p#S87&0d|GG%fd`jQt!ifM*PNR~+i=sxr84y2$QV>IHtKcH=1nfncKbqv zBGGO0%So8@Ot7w68K&{tPd{Zo)i9qj;6hQaa3{d_i|MgQys|X#5Ib7lk5zgrJSzn^ zEDS?07+vi|Mr@K5*K=R6P_V2Y#)FFnS-L^-gta&Y201T01C!((>^J~hp*Pnl`~hSesYTr=%S!8ivh> zgFffSscSr$LL=AnK3ed)K|^ z04^axhhPoi6L-!mf%tWjJw@`Z+bBC{nn2pVESkL?aHP+>TF17q^!aLozk(e(K2K)sVi}8CevY+w?&yk4Pi0D zZpDoM`0K(Np`1uu>G{`c>)TWX6q;>n`L%1~tMp}u>^0yF&N(!u zn&5QQ=8~mZpwr0}YrNV)zN4jtTgrV}r$JqX{+YmI&O4~T&ITc_LYA*<5gGo>Lhc~y zOgCTFd`xz7y9#x4tV(c!do+mJ;u*D>;k%Pq5vs+n4Rbn+;E$_T{bg4(nkWidg{@Lv zoLQsngo8QB$PkjH-*iR2nUw*1%%tr>WiIlc4qo5!!O`1NN8#YMGyoBwA==?c(iCQ~ zl~+B*yV@-05C{jX8!n<*G5VQ{WU0t3zC?a9V|ljYtQkcUQ~m({M06+`DQsJz{B;O6 zv4>FY!Emk)b;@Jwi?^D%uAG*{P8AZ)Zm{mGCm?XxQ{3|kClQqUh7*7Dilv?FMn*tG z`nVO6!CV%bj`k~i%6C)sE#@Dkjug=D#w>Mo>+t$ec8$Y%WQVd2EFE#^Q$$-#qSPEO z=aED*xQ8b?VR$&|cogz-XjI5NV#tHubwS1(g3JD=CrlK<;_f*dM8SkcWAQBXBUk&` zyyfhU{kfFzvVu|c1-S4k(4W42U!;u`zf07pU>kyMVf%Vy)Tgku46);N7LOyL~7@&L`J`rWbXd<#bY(ZB{TOIZ$UsK#4M;y z95VsTT&-Xw)XePr1dq=Y64iG22^NUedrQ$9=L3_b<-R;zxBuqiG2 z+&oyrH`!%!waoC5OKlbnF7`E>?=^!3gzCx3JjA`BR1J;R#rMNOlcV7@Q;(#HvfwL^VpArZ{Zy4Xy zTs?2_y$j9xxW@NawutT1trw7)LKM=K9vlQQi29;&5k)QRcz^Pe^U-7VNdoBU`8W~W z)^Zd|ZDSEZSUy{?t{Mp3$bjq&Rpj^$zoys5cTUqkbIFZ3WCeITdb zI}N$&50W?p-r#=^;l-#wH~w)$_+QcPpOE7J)gk;3S?+&i_D09q3N)>|;9>V>XsjRY^0 zu@^jYHTVuvrL;sk`Q9wLjpt2?Ko4)3tWlX0lYSPMT9o}1Ed4a%URL~pO;j{IGN;l3 z>8x1;(m?9)7qGr!Al$GiOSC7UDlAH&1;m{8O%$u4t|_qC0uGaV$46HmN z4d;mMjsLKI3}|8}i7D$6=(?zGq%$ZY-JYDJglP!V;tCmtrAPvAT8>{{58&YIavIvA z(}(DuCH*=L6-Pocg7iZ&y03<_P&iW(y~BPTFXn+5{rbV49Qt5WyME%O-Ye4Or+fvD zGz)^|&>X@9Fl6_lG}tltcbiv75IyFUK0nLRp18=oGu!i$lmY#h6(XHH+Y;N_N+>RX zYSP%2siR9U5f#E4ecd|eMvT=-liN=l?_v1d>LLPi5}z%N{QabmdMgQK=-!dlTW}0F z!VUmNE_H)t(zR?UIH#`WU43x)Y&eqz67Q{>m+qn*o>Au;NY-Pw>iRIOD0m0DED)kg zx0)G`2(S(3Hv%D8&HefWqQqBtqjI-#tAiDJYwLMwSSaF^ZX|s}06hPyHKdfo;}gs=z8lbml1sfrl+BYXkyzzb=piXHUok75a;C) zx(&mLdKV8-4T@P!D>?V^l$ zT~57wvF_L&H*z_Ti=O3sD+7-{)Tof2ltK;1tf!2j!G_#d9@j|kT)Cj;szIio62{3B#( z_A%g(>=j>n&5-x#HW}O6Ao>H`OmR%}%UO0}-ckOe7JhR#N=~Tf+rbaCslevsJiXqp z|1Ot%)jpukL`83(^?9yyRTRkE6K^gtaeA6NyWS(#p>(B|AJ@HjQIT#GA=56OH9DEw z;ocZ!b-u}BXjD>LfT`dnz&P*n)=RV0Dj8W$LLT-rkbbHQ&UhN8>O?sEt{S0KTyA)e z{kvRl>OV02i2UyiKUk<=HxzIV!$2}^K6iH@9arzDrasnKM|U=77~ansA|+l(G|U3E zS>4uQ^`4(4NPN!&KP1gjJZHq(xz~$11N$h7F5;u@0+=b6UbL+*`rVYwp^gOZ7q!S~4Q? zAhP9jN!GF*_T{^|K~t=2*YT2hX)nrPkK;iN>efR_<2gvQRF=iX{?71dMoxyL zs4=$<5Au(Ek+9FwLODSs%yCUj-kSP&ejRZTykgetGKgy`U(fCQ=6RLg(55*EHAsxn zDqKTK8IWM&zd#(-ZH78s;l%SS81jc+Jlie)FvDu*uJ@k!w2sHBJjAZvX*_Lwc`?K( zSe9)@Pkz0fmHMldXIc6(+jhxDbPOtE z1uUol!OW(1He6w$c-2_nKahLpR~M6E1LY1#efW-7Cnuy!`a{EXt^z0~DkfPZsP&6B zi-O%&Nc(oA(Y7-c#6kpFjh7T6JU^EipN4B-dVx0csJ{j<_wRwp8_BR-302ux@In}8w3a3Oa!n`5hYv7vv6RF=YQX+dS=!f%m{#hcl zR%!GiRNglr$K!E7v)1A&kyazT{ZtfgcaG*MSnYu*RuOCK6S6(ezWi4G=?6Tt3Wdjd z@yC+`t%}AGyIiD`QrM_0fNwv$2-(Jpc+!&{uiv-DFCZT$wbqSXpl|Z2I&`vP)cRm1^2TQ z0KRJ-yKjoYEX4Uk9(OE)8hE%FN|^m5J;N_PIf~p1VPOZBz)@BBcsrGV^xL-i@rGGKFsN-zSZ5Dv0{k8J-Ze=6M zeG$L;Vo`Tsu9RW(CBqYyBx!>c%IU`JfeDQ{C<0g*qj&zxiMZgvHGa!ESlFoE2@!eH zB)A3&%eR=j7!YTDi28Uja7i9&>k}ZD#1(ENc#})9;lw-86}GIrGT8(`x;Y7y=MFrM zfSADxGIH(J+Af68BI;YrEszhle;t37jsFBOZ+M&7+ZF7Bz7FEvHe01u<*v#>u6dJPbN z>>pK)ghqyD{;nMQ*K?pK;5m>8@Epj=>(}ss8h`iY)7z--iT3+5*S*pb4~=Tc+iR_= z;%45SR?6QYemN`B=2E5D#nztvP#`ytfUNs7Q=333#>g|X2)SL=)#hMiOzArvH*Mv* z1L2X`bNun{?QSfm@MH}g4y{fS_HBcvd_5OHN_E8}q;#^&_i%N9>>-M3qG-NhF)jW# z#Q9Wuu;gYvTL(OjQRs=rlGkS!qY`yx*OIMLDzpU9BJ-rz3OX9e5$;fDnp*o;I-l@> z&Pa0$5v9Npey?S0!}ERB6^koAQIHwB4PX0;gU=JDHtk??RR~GTLIp5JH3Mj_OG+st zSq9|;)_c#w$6vmHBHJuRUM%%y!A7rpoPeaxL|3xI2MK;5$UrExwyuEp%NEW%m%K_hh`=Z_eXp zVy0W?BC2T0g$jhN;U*&vrM2U!VArCGO)X4R+@$ zlzSQLAs13bVniRcW1nA0)hx$Nv1r9WLl+Mzn9|3WmviH+d`^g_x&l6y-w20|O|I%m z2Ty9Wb3lmO@IrrhVMc?kW*{lV^w@Py7i57ex4!X_g->PS64&sWqGJn{1<#F6sh3K% zv=+C~{EF&Ef6+6wmEgFL;2cSaQ3ID|LL7&udV^OS^NnHLq%q$UsEVJD8^a~@5Rf!n zx~6>J6)df5HA}z#n5)OG$`QyUBBA-*KH)RBd_ zC@>u5f(wdho}jj-H;WQ@jMp5-^Q*bFduYACh;o15rVo?``=_)?DYM$81h;a2hSw`3 zPF*Y=a&|~Ez_-UiS#abke8I;w^5ycl)J}}zq>6>Eijr|`h%jRD>0{>A6EZKhhg z03T*#qum5XZx}X&WtmsU72>P~ zoki3q=8yRqjRByiRX46vZhq*N1sT!O+gE?DlC#@MAN*Z7^uOO`{$GpXe+R>lFw3XHHe>O{Y~HID2a{z2 zYwQD?{*$K;)7A^-9rEi2<19BFoHcXDQNDA^>G>|sv8c-y6=m)3w2dq>#YJNk)oT^A zbsW&^k;e?^-x~)=SvZN>1w>vQB+HExdF?B# ziB3CpCbDqNS68x7v{sv=mAVdSF2d+Lxnhh{0O1g8Evl_8!zLx-nYBmKtXL1|Mx)=> zd27VI0L@4rLY27h*0uEdp0o!{oZ95qwyP4dg+!)4!Gu!Uh&ZF4vmg}x62q}9%mX-9 zL_K$Xby^L^MZd@uO_lN33>MYqeo*b4QivwqP*@shN>)9P2_&! z>v`NuKfH6Aa4Phe$lMYxa*%wtMb!-g<$7poBQvE~t|L2Ni^p>D!=Z$+@^{eBPM0L* zTTD=)q8q{Gj?sZ-gwwh#usZqp&;CSxuNjVL_&p@UI>hC);=1B*tqJ$*p+b=vU%${gFALo zU_~;^hES0wvu!I7dLyU3J89!gCi?AkXAy(#Xlsqo%*A0C$niyJA+g=sF@F#;J9o$Y z#D&evGe8|ix_XZFRYLQ(FC4zAE2mIqd!vF|NKhx^UgR?#pyg%nP{d<8e1(Gp z=jR6`8VXqS$H(>7=U29w?E@E@YUD^-v50ltQMn(W2uy`ZUHGCvJ|YAVFCY^tXF8&> zmqrZ>IGl0Kk@Hi(v>(w`}JQSi?~NMAJd)=0_Sa`ph zFd9wP#G3860+KG)znn;f$c8xBgYBQ%t5apBoDo4(Ug87R;=rV%CFx5b9S_{;d7Kc8 z)VW9Hve!kF;t>N`aw+G3izpMTk}#-hV@^3m73#cvQKXe_KragV`Glwq#EutA2j-6y zL)Yl|pO3Wt!>|Wi8Ldsw^lAv4>Og3B=LG% zOUg~7&L}{-UDJz#Tq~JbZgk#}v-(l)%_n)N9NIyCut_?FjYz+W#0|-WEB%P<)Dd@{ zl#%~ns&J{5k`3PF5(`_S4xV6H9CG6TF~?BkuQ=osQ%tOxl2&!?0&?-)!0?@Ly0|Yl zWTtb63G#%+rgRjoFOn~$w2p&>Rk38A%5cGMCQ9Og`;eaK>%)H73DMM9W-;S;X}0h! z-+%#gqTBA>DAqo61S|ExoC*szW_qC?C<|}Y;(Fd_A*x^tEwrM}U(;)UK5kIhigvk0 zv9RH&!Tt2~YB||vDVT;Ygzn+QlT(K#> z*0pU&onM8czmlg-UgUSzma};jH5pdl=VCjICYx7k0g2hQ-x4FXPY0_WyM=8aQmv2| z@%xyQ8A0$%fl;T2*%;&Lmb-kPPbMc2ODeACJ5`9-)Hj>-l^xTQ5@b1Ny3g+!T(?{Y zRN2IthMAaOol949r&2u3*YU|n{fy+GzXk`YP;~-Ia6cB!S^Sikx^o29PPmfN8oH*l zyBE#DP6x6NvyscbQm{k!qq>LYe=hNoca!1RJibvNA0I>ng%}Yge2*LW(f1{Aww>Ue zI6L>3h6ubaB7nvXDm~P#G|H7(2m>I3>n<(V<^5_d+7mtGJBT(tKNOS6HNlSRkJUM% zyNI~(wxSc?*J>A?Daq#>l0{Eg4!h<;#k5gJ0czeDojS5VGJ5cK>F1RzG%p$S+m7N_ zRG|R=^%bAbjMz0JD?NO7Ep9hQWNg(?*-?{1cL}5Vyf)(tTYLg8LL~Wzl*4uamVDQ3 z9j7C)lDJ0aKvF1zEE4@LPM&ScjikD#3GjE!80)fa>=gW%#ArJb2HZsx-+y?jKk(Z-`Cs~)hpA)L z^P!*6n|44>_tC!f;}Cx#%$ZC|k_a``%$m1Q)UKMZO^lYSlSe)I$noKofhJ*trlO&U8zdw6j|5f z?3)(N(Cs(hL^f9Yq%Oi8!XBoa~&Al`)*E|73OgrxOlQl&(*s~e5teaN0hrg+%m-*UxQ>fuK?|zs_dV=;crN^%W&~@x>Z4r-VwVHnnm&-pI^} zD$les+b8o;N>jY|MRqf|^N|ySSkK`M@H>bW&R?t&Tt9cI5Axvv4CM!aW^kSWN-#o6 zQGtU%q3_9s$R+(>+1T<$Q)9nW79}8oiCX6yHee<>5dBnQwo?lHoD&=x*8tgc0#Wm3 zy&#mz4&*mQ-Pm>*(Fn_V5Ix$BVsnrEv ze?Ow`!Q4iFywfm>Hlj6(y5vSG*nY1CZg7M@EngmtRo^4s_+&V7FW_LGm4Ukl#o9!St(VyitOLue5T`Jh1R%e55vQpUK&&Mg#$$^);+M zE8`%7TU-wqGC?uA`2z9HYT%#wk^f47{Ap)x=mu*p8_TC?mzMS8cf-QMz;*Mk+o`Al z7%aR`n??k?poz9t1}4zVLS2Q>NLPo|ae`D;9CWM|;=U+mgP^@6@vHS+t|_V zn@gY=i=f(q&^-dK!#OF4|2qqM@&(HEXjgD0mP=o2G!m zGJgN2D-VQe*Ad+Adv4E@G2A)V?7OS{kB_)UqB*sGX*8Q-p@ktc?H8O~@-EOR_RL!` z?YEQCKpP4lME`QN5u(^92h{ye|C90C4mf}RRl?!FnZf_9G~;haJzxI#WPf0IRMNi>P+3uY z<~RdAUCsU&>m~-p3OI07!9>Yt%lFirbucUXv2FJVAoLO72R3)Ua|3UBZr)Dv2seGX z|80-?d4YSeTQ`LFLtLeH=iBOHBfI_jI)1I2XWRF%m)c2_{22|)>Xmb@E6&?7)f>C) zFN>OdSG-O+4Av-)Y6%4h+m$NuGRflQ55zr}OE55)pN_bnBb(4kR9an~>@5~stsBGp z&pT7PD}V~P-l{8z$*7J(_S&gAj~}H4vFm4-XF18M==im555OKP^C`7+buhNK3JxZl z6qi*dOn2>c6Im{os_xY+cXL=7XbJ&s0B)2jo_Oj z;$6?XprWN)$(vT=k5szq{AnpD_tE_au)yZX$PzP!BAtB`F`Fq&{XTtT`EG$TWKhtj zA_r295*)I8-mh0u5kwSCii(BczX}eOCS!S2(X915n%j>`{NUz7){a&v>!5}B7BlG{vp8(L=Q4y!-x(S= zT+ReZ4~A>cP+QSR1@(y@fkoY;*&<5@B3zgb?lwIvn>T+aa-1;ADQ%&37In7(4!aw; zzoch*UZP;x+q+)liO!>MLPmjJSj8rJ+gY=l-5L**l}5?>M74T2EjZKJoNK}KbZe7I zDr2@#ZV1@88%xkj?5Qr$>c1M(GhiwtMrS_t$a1y9z0O3QEppPyCV*9i^mT$g5q*vU z{bbD(J1|HWTz~TGVQ)b5J?s;5ss9FJa*)BUpqQIrK)rVM(3t@THU}U$(qc)&T?_Qu zD3Le}>KSwl9^Myf0YyLT=LyZEd)JO#B)JF?am+v@?G&Fup@M}AA1t#sXRly51YhxM zSAU0i<*@@}Yn8PlSX{xuK)Q$Xw`i07B@~>%Lz9@r$t_NTfEv>eolVM2KUwhsO#9Fa zclPRg8oAXP<#Oc*Ub%>>Y<+3qWp}5k%uQ4Xdp_oXi^nOg?RxA_P^#NO2WP_BM_pND zpEP?{GXTpO>Wt+M*cWdh^O>^Y!!uF_L6wl~StEU&%XJ@C)wl+%tXoD2EOqNo7~S~R zjpxVxdnK`J+FuDc`sGul;kZmG_QGP+F9}$g9DS+>!|JDyKt!VJAqTyZ-uG;O58ih_ zFWZ%Yy7zB-{q+^ke;Szb@9%j2j}Z6Y0^Wa&g837?f%{8f;&@Q?gF8&GbZzOY8Ze&r z293szK7VZIrO4Ixw~cU0CZQ@zN_9c==%V}O-)w{ri-e58W1b(tW1b5=xA(D^X2!aQ zm3I%FYcSF4-Sg`lpSAW-OJ~>q{mEHt`L$}zRnelG)0L7n$Dj5`BdRx-TNzoZY*!r( zYQg1+%EcNb+J+S*qGaq3N%-xen2P}Fe2XHo-NZdr%yml7lm(Nf6y;IXgk)5m9Ot=; z3pMwkw&XSZJ(N!+bxwS1C=Ra1qqO7$JkiEMC-^BQjh)3Rusk>i>qop_$bmR&8SVH{$tAK1RCOsiyCURjFer7?goq5N{rb23N`j?c!?vEE#Gh zl*TWexMco@sa<0C0lU2QNlPdon+|#ohQ5(uOSlK3UcsNEl7&14@6tv(8*GL4S!i` znGO9qM)KCPn1mMf5E}mJIukZ`yTvqM%+G^71yN41JOg_+g`GIaVT!`Ul$lM1E|JJi zXZT0SV{vq5<{q(&TB_v%Up_%8^9H_9K0kBdg~IH)H^78bI1$dey>e%m^iz-)F1U+v z%r0|tY?^{vD;(+L*SuXzKRn71IQT1PN@Jez_^LSMrR+*oU9b0XY@slN?h&0~U8Y5t zeQF%eSoTn8O^_;)Fy(PlkO^@rrUIESO&mOBpZK;3Ut!Kpcds_q?2t~5=;4j~!_9jM zq1IlgO2RrH^R;Dlpbx+-^hFA)`%7>l9vjk*9?u*%cAS})`_jxp3GR#por+rvnWkoE zN$qMEzYa_cE^$VZT@%dfs$*)39fade^?w5e2nxG>EbiqsaI$-f3|`6A^5jRON*#Rt z8rClNobb?3P@l<3lfO8rRR?HQa8kMeF=vSnG=l=S^!B6R_A&9eq|9m9!8732#N8I3 zcfSqHz2ccbrsMXx4GH<=;w8db9QV?}n3$sUOz_?_mxB#k4|s)aUgeWb_GE4}0BUjrsPwnNZ(oo}{4ofSJvT?}p(93J;x9 zAa!+vwGCWviTA=>)RYWdV?oRz^9~Nmskt-c?=sC4qS*FRxoGaq05zpkCYbJc%-KBrmreO61n98O?v3y683$)%Xu^g=BRdct zW(&zTOedE@Y_>CmVqx6p=5ot(Bij0m{kPs3(=E^HH?JF893LUisX6QiO7~*%TtClV zw9t`NQ-z<1@3iM|rl(mCzb-?&tUmOczzjV5Jv6@Sp7}ogP4I^3jqQ;C$8!6Rbo+0? z?f>(=31f;XIuAcr!^7(vp=n zoS0}ttb!YJvi8%0d){H+c=^Cf*JUwPTrB(8hJMve=gbvSa)hFNEk=jfwWPQraW}O= zo4=;8kp*m*-{>{=7#9JMDCR3Gm*ZyF;WaO22jD0gRwB? zn;Geh2s5{Y5XE&g*$Hn7c~3%xwAjs)(BRiw$?uR_q!XQ1f*NaQR%>Nm3GLCJL1^fC zuN<`wSYs)@(@lKsQ(U8u`@94XIqPb)WczTL%UTfKrjXy#Et@DEmivbIu)o|(!X|k9 zWYFD*uqP-vc)y^+yz#SOmI9-fvstU^%EQ$$R-RDz;KzT`p%L%>rWc^Dd;aQD`lT_! z&P^u8=j)gVMuvolVNR2D6e0c4Lrc?RDBU4JHD|=i8vTkzS?|%#rpxUr9{5s@#9fIn znik?`ku~I-S>*Bz2(=(`G73_8?K0?L8f;ZV{-^y~kcT*fS2=gwTf%izj;D-qo; zBWRhnx9Z3b6zP~`qQ{}Sa(7TnCXha~_nUj6eji@hy=jmG$MFhyK^0876H?m}!-#gj zhtcMa<{a9UfwA8(Ix7}LwNTBwYE0^0n0^hmw=R<_6se>@QeiS#$iXJTV5;xIwi1e_ zoat#pTjoTik$G*t{jzo9`02zMxV*%av8g*$v9fji3}69+)E9jd`TmSSftOv*SiU=$ z{0;F}?zhd>hiSZofW~dzNUiE?kX*$K;`J+YcXGRitUM*ojHJs9OwUAJo{z|ZX$LRK zug*4Nh>@45hSHLGENFJA2eKjh6AIj*sVj{1{q&x29QuWYllA1uMq@IyiiH8ojl(B`M9h~Ft6SvgIXCy-p48U@pTPM> zkc_CqLfFVjJ49ZL(e2oMrw4|@TYHYT#ZPz_zP+N2eXs&MBiSx#=)kOx5y5)>Fz3mS z_W&?M+(dutKKbzE8~#-W0{p0*NTF0%tcGow`bO~1JK`=<{Q=N$1=+?qDG(i*g1KYIS zO}#3s&CBz`G+%D;1!`L3;8*#0`>K?!Xsfb!iCUd0!8veq*{-Pc5Y{9S<5=yeI$Y(~ z*1UHQ+%M{4WNQ_e6~L1?E=louia%l~4K^2j>=+ja=^qbnyvJsU+4EDl7+q02>-{-1 z(DDTI4PGC^jAv*WbrP46JGeEcJDXjvQ0j1br{EKH+lN--tJ*U5LduG|2e%mS%<3gVV2TohoX!*8p>vyK-0%jVA>be}1ECHA^}(ZdZ&(f0$<`=ZQsIsjpnDv6&ZQXHM~Ahk!)hkl zE4^=2<1U0AMAmIitjPTiwn}ES?e&f{-Hd150ysW?2y7*@4YT7x9pE9+cGYa(a-AU) zKX=x#uc@p9?YG>l%J62QpkoRAYV9NRYhW1Xl?{~B^MuhjV_ z(~wJ$3=O7m-Ed(cs!v2Hdm(9@){Z&x<3N3pR9z{BHSS(4Y#8hGnwB4rT1n&_cY7}ydP!#UDn34hw*Mm@eokVZ4t$EdaEoKv;5$rmT|qyLBJ_bo{=-?R5mz-#(RoG_#Z;~M{!D0#12#;p)C$6XfY z`JSgKac;ry_db3G0_7Orzak9Pcr}~QDcjW@e8^iV$vG&yO!aH+Y#AiWJ~3$NsgTXE zdsuFUjkoYxCufdUZI9S83UwE+e3{pMUP<=1H>`)`x6Q#t2q$-T(Ip_${VBiL?iUkH zjRpB_Qx=CRH^Dwu{=OqSc#j?2C65svS99`a4X)pcg!pMKU5Pmgx$M=aR=w@wF7JUe z198da`4IfwDD`cFY);TIEf%!|OwqII`**i91Fhwzn4EQqvVr`J59J06lXK@-pNsVhU_>9<#y|6A=R|atSX?-3I^b+Po&0DS>O9pD-(}s; zX2=KEyV))IJHfFP>KZlvu>}7k=l;nE?gSK${;GlVuVrt0`!7oW)AI5!8NM1$Cyg9j zZ7C46Ra8kbf&2uraaQuB*Am%;;P(MfbLdVVc6xB>$XMum;@ivS+u3tl*RQL|lM_ZS zpEvvE#cJP{u3r-elU~32530LMhv?t0T#rg}HI*E=e?5v6mTBcUG6%hv+AVu%djro0 z%Hn1mD?Lu!mvsQV%*-*GyI0>A(OnK2lA^M)rngjD$18c)=$7iatj`@d!nholiq2-b zMz57sYdM#$uOnYh6%piQ37>589diz<3ugN?bHa{Q@2DtC}q- zEv{zlyC@&fjk?Qw*hsRRol06RXdgc?;H5W|^0%kAqN4?qwim566>fWgfw>x-n0)xf zAVbZM%>P^;hBc&-tclnp=B?>K20J#QtIe6^n)#C~;ww+&<=jh?BnbO(VcsUijAIC+ zcRCc2YzQei5gBmw7cZ%5O{t1A`sUnYJkV1~YE#Z<$jJA3bH(5%D;l@P`@3jsY7TUh z7>q=LoXt9?7BLYTIYqwoq#22wnmIUVm*_zUmkLoV4nZP`@=)hBM6AM~KaxO)_rQ8= z5oBHn{b&fvGfurp0O(T}x2+vml$@WH=#>&7_>ybk^Q^(TBI4(eHnlEFVP~fR2z}_V z;kc42R|2vK`CHBwPretj(9ei42HJv)T?-nq1K+mP7`no9caE`SdCAUU&D9jPSak{0 zTQbl6W+2RSAqJnR#V=cqIlQ@hI}xy`CRq(fSjx(ziN9HY@!%5!MBJAZ)isQ79yj2c z=hBF7o^kf5M_+_I_Na39(j;k)Zjn)mLbUpcz<0(n@E;Yzar4u{udP4DmvbxoazvhL z$xjR{S9)fJn{Y@H@j^7dbeRqGhpa<(=*;QO(HMw8c6gOZvmBJC&J#&M zY+LH^FCARmts6syADV1YoFerXdEF-rAlAwp-J|%5YvQ#57+sTu)FW|AlJBpCPmhEt zw-LW_6v8MQUE2j|Htn#!c?-Q$w-S8F-B@hO954raR+NsIPYeC*qvBY+9P2#Hc|C}T-U z&kfp!!N|ree^!_4PN0M1f~*&%!1%?Wb*FdP61LZx+xv^j>dve3Hz}K8-{vS8*i}^X zbz;PF$2X#lFHJSDBor4pQEp#eziHe;Q<2N-I}>K=^af*{xS=E+ylpimA<_2pKHmN! zaH|HX>%{)_?S+|k^6q7{8z^`~Lg};JGin1d{+nZeEr9>0wVVGt0sJpu_fH1$|I7WQ z{r`mVzc}FmdQfbBpJ6Vtl?WP!Q6ybO^Y;9U2PHOU5>uxtPAt{D;>^WK#kBu@O~!rn~Q(*U{>tUR86q+xy^)+J>)JeCOh?bLU|tq~Qr~U>M3qd#PoXBMG}e zwvFep&-@An4W(yEW`TxMjIdQs$JhMCQTe*1xV4wUXA>T^6;nRGnfW$>^utQW?h)F##@%eHlu&ogB1_n)A-*{J z>O?ew>3H-iSDobf`*ejL{YpQx=k{S?d9*6&J9kj@yihpG=*uk{Y-vZAQ_hpXl^LhW z=bZ*Ji#DuNED&s**UJ4WcEnNbX;V}rHkN4as_;8W`DpG2f~MU+WDP4k%>00I?Zn8+ zBamP}2&RL$ZoGpZHE?i0!Ra)6MO`3qh;8mGgN+N>NgoECmuPFd; ztvd<9^A=Em+b>z)(&yRQb2q3`V>E}yOvDOhpgRu(Nuw9!dvshn?QjgibDi6UwJtpK z8K4>5kzQ4tx)7EmM@~^NvnlY_8(gT10lT&7cSx!qj_p6KT0R!IjSKL04_(LKUvXD* zD#a~bN6l+vVS=V3uJyjxNkOkqs`+SKW5R!;Ps8CV0GEsn^G41SX%N_5!%8l)HBE`S zqNhd-!CQDqd|F+4HDjRGliP$nGm1$0Jcu0p;Z^nb5$1U1mu!E_65_y45L)Mprr@wE ztix+$e1s(G0h@=nTc{sRh(;jZ&5kdjGl*3i*lY%(@NdIoCoM@_-c1AoZLoF7VH4b> z@MEn-o;6s0KCE!SBTUF|##vO2mlQumw;Q5D(@&T_q*MIBfy{;VREU_jr{o)L@K$QX z{8eIWie(O-$NDlw2LS~k$!%imKbC}{6@zTFb}NxfcG(3nA+o+c*@mz0){^b^8Tv|q zbU9&-)&7v9ggudr`v;YY9VZlT<+?(k6`#*fm)(q=uAhtUuZwcw zm~T|eC3jU)dblpBrG|q=vmr)wfu5~c%0roMD5VDDgG1osWP6rxF@T89ccmZ5Uons` zKDzm5CL2n1+$=TzGfu@1PHMq3qmkJQX@x8Z`6beVzb` zG|7Jel6rr&LxPAJ}*3L zb0U>seQesBqTCkq09LoqzrNR)0Qr3OcIVRzpCqS9M(&>1C-t5RN2~4q>b}+Y=DEp|qUT;n-dal;H3; zzu21{8xtcB1c}h-`W&Ms9C8Z6jGr!cJss)&#<&?VF4=F4|0DO9e?r|qA;ka7)A*l~ zW&d&-|BsQamKMEkSZg9IEXQ<3Xvi>kF#@mlojSI@Z{D46 zgD=oq_QFq(GwLYC@#O6Z0_Mz~<4FzP zWIYo6KrI~4spWZaAvA~H-I!?Egpr{Im#JNQRd6aD~L36Bfw!Ep)qk*3H&m&XxaokFtnrQT%&IteqTeQ#S`5X9C-RSYkG|UjVOT5n+;FRdNkU-;*gnY^?>oC`mAZXLr>@qcI}WE1g=nfx5H zc(fK<5TMM10l+6H=E^jm9EXC!RPt4Tz4RC49MfNxO`;RvM;J~Vu+wKGidCYF`H7WV z4C9RaVVoUDth*=%Y%9h*05_APCV}!|IIeDG%jw&pNY2hPp!Gw2Su+KDBAT1sw2MW0 zyj6_TDHGt+T9jkq>KM+E>o(ye?-ge%TqC?t-sEeRgje?z;zMr#%PZ%~VE~ULyzsqU zrT<3K`c<994Zv^k+vWHt6*T9`w-AgEJis=#Psn}ONMZ~9KM;Uwxa*1XYN8KbFNfZ_F*;R_H4ycc&Ghju&Uh#N z!4Mv4RsHJKo`dgqFir?+9d*x(svDx>u`^QdKb-5JF%9mrI2Q;ZVfuDtAFHyqmdjIE5n z1)>zCT%-qNREbO8kwV5ZgM>c>1>x^&%$~GDej(|Fy%Y%K97sCOLMU-Uo|hSVzaub zlv=CydBs<d=y1PwTkP z8?EgeML;_Dpg-aCmg(c!lHY6(ut0}DKy7X?^#Ufrj3T5iM7Ahn$_hJ~l}?XijUjZ- zexn=b5`^ff$YR+r6n_8)%>H;fI;)kvhxi#*wmJ`sVPrY=f(ILe8&|DNom$`=C6>K@ zMh>SNl3BbKuL{K9Zv#7`NLcp%{;~eO!bS?SJYes4O;U5MG+riX%og@i4C%k z^K0P9z>4W*5Xk?bVL}t_SuvYjFLNgv$}T|B9ZmR31tAQ_?pA8A&uKUkC)r_vTZ^7= zSR$P2Mhc%UsNZzad1dPZ5&R)1bJeU)E=qH2G$3`=rM*7nLkbZ;%joFVarJz3Dl$yS zr{wjD_`L)<2}vlCpW`0Sr3mY!taM@F?t0gET)6PK*4cZ0XU{%+ z_UxGn7!6@YCQzyCS!;oIYA`px84Br3cN4s^PWwwd3UBS%=g|C^KYr>_LP^jKgKpFYg@ClPooh-uqYYot~p%Kdsi zhH>%8<&MF`bc(8rVB<}p%ul7kQU-fSIzQg-zSGwjTzq|SxaYeIn>xqE&AT^aOVI2{ z%-0D{)L-R3VeW0Kka-ZM{G%)!A<%H=lZ;N~WbOlHiDG)JIzUFeuRP$ZFAhQXVp|AU zAXNGqrcGkUiJXuC$dCzX@B$?u+QV|w;zhl_H) zjRCC0++h{;COP~ndsx=q!qkp7*sD=jOQrP*?rZ4V$FH>wG@@IR0`MbeDm<)=@i$TW zgyPnNzbVbZyhR^A5W%~1u-yam{sH(M%;_#`N801COv5^^xVQam+Qt4tgQlA*w~}RY zHuqb9#^BN`WWE3QoaS|W_<4TrALzrcPznxe!(5QngbKczFOWUsOOkZfBuDBTpTd7) zA-e5Cn z;(BbAMfUCC2F*iN!-Hj;8z@rQigy~JZ;2m`^f9xM>E_;)i64PVrr95AL$$JDpC=CX zxYyJ(v2UWWA}#t53$nFVV~LX_tLXz~nY38^q{LpY$L!&Wx0yXVE@2Uugq5&(Z;8=ISkkiGYV;dD+hX$R zUtnrAkKP-#yQ0bWP@2@~-u!{+Imlu6EVzpb!q#0%J*yYD*0r+ZCCb3qvr;2>G8ym} z+^hZGRi+-QI_xD+XhVjjk15)>EOp2j0;y1RjU#1)I+c!n5F)-j!`b~HHa7n$DWM$Q z9dj6ae|@Ukr}_q*WQMCEa!LtivY3P)3;UsXEyM8r5KkM*niWV!z15sgYoDy!>J9oT zjb;sq0$b4n@*Vr-Tx~q32*l*K5~WMb@883Fz9sP#;gQ+XU6SOS0PR&m+_0s4EI1lH zoVeA*IB+nk*iE*=V6%NN?iBS>K^n@V0=zsp(#Y@?%fg7JN35l$TWe!OL(iU7v4&vd zEWchdS%jvH3@;Z&Kv2%PQz9$VJ}hnkSOrAj7-K$mOnk$X`FY?M*cCZ(la6G zc;-4I3ee25B;&9$RjAB4-_FDHv#jnCR%s0MQjd|{gXKrW!BFp+DC?aVq#lzCf`L{* za*`12k0%)w6ht6|^d^UUIu0XD)Wrqi;8UUvyYd4HqQm_l5*~3ghQeilso|R_UJQrj zknm$e*@q-yAv^LXvz&bG@q*9FcK9+4v|sA24#0Z)Il>vq>KAe?`u6VRmbQN@>OEi} zka;1F!7#>RSRe(nzHZ2+vMu)*Q?YU|h>jp3o<(=ya|G5QeC?+Q>sZVHg*}9cwa+hB z%U0AMQyY?NR4r_e{`BKtzh?R>{hzV;^=iUF`MQ6Y7mozY2(SZoKR>N!|JQjuKP%gf z%`G&|bdAka`2ISl=lA<65+JK5L3(r1KvKZT$p1==m(6U653z%lmqH0-cHZg%EbQsc z;Pck1i_r~;EC2HS7C&zrAf=Msc(8ul7~go1bLim6x^=WD-gv-RsUl`&RroZ)jO|x;)yUU_Y+Zu6jHrZYAr_!`Ijl*w}0Z9J3TFiVPMGD8xpJ ztp)W?9hCf_S2ONw8J0?#^ptkA^hlst>P4pTHzk-Ocy#TN z_$>{pR?BJMg2dJg^={F`tp?4s!9G&4#nhatwHlrkE2&nvbvAvRZ0%?oJ6-5QijRPk z*W`I2YD5ku`NZ~`lnARFnLna!GOLI>nsctbS!N=xxH0p5)Dhh{!l}!ws#$-XHHq$=3rX3m7(8 zUb~DGW+@3XuWEVH&1A{+1c`8~Fixq46E9Tr9X>DV6z_*icq&0pSPctYUg*x2E_iB^ zhr(j#7f5q2>j&7SXFcM11O?McM@AKhENivvJGz@>kbs7f&)ojDo09SoWseb$XN8js zY_bmuT6}I%)gp}-2~(w#>LZ*4+J~kj1)BS}{nir<`%`Res!6C+fTl z)1jcDM**GuG#kuTl`hEDuD0u8@pKEH8!l4`#rNEsl%*5kBwo#>1^kXfPyAb|%I_b_ z`g$oRh7v}h^B-qXFulSG`*c_=33r(Ao(c1|R0u}g6t%L+U6jP`ml^L}Hm6TdUTY!r zi|T4Idg7hqK>Pr6xa+>}kf#iVW&w+FUU?!pcEla`0kI!|{Hp=C}GzKcvy!F39l?r1wjF7OztqV?Hx4n|KklRUX_xC|;f- zjQ-|Lq*cBLXPKsx@Tnus6pquPSld5s9Y1o($7(3JvNDZt;UgV~kh-TMuA!UO9&(^= zIu@#{$ILbnNv@B>9`yjRo|oD*vP3CAgiMHa<|DW?&KD!lD^g}d8QgcqmK?AMoscnJ zl6+LyRiedliS^KRb3Itu)U7MP4{`2Ai{h-C8pUY~Wu1Xktn)5=nNh+HICM>VavJPO z8orpRQvkH4p~!rDQvvHFnR<*rcDDFVLs;dW*S6@+T;r(ZE!_fV`r`T(5i2@mnpBk3 z)=><**9XiEjtW_Ps1mlVUhmy1W&sCiM&a9N+;d&f_2djjc@@tx? z@yn9nWU9)hUdgK$tb(gI7367eJb_6xIizZoJSZyg!THfv$u~k^VX|GW7E$MUMJ9-a(`+o)h4^ia#Y@>afzhq z#kk5b#A$YASNaLs>HdVLF75nDPC?K|J^b$7ejWJm`~RHd_x``~>=#|K=@>q$cMos? zM9$okrvwq7-H%h8Tt;F`1PJ;GN%qz^w|BB9ks2GccYEtKqi%CLRZ=pK?(E7HDn6LYToA?6O-X_EgH$eUNNzSdaVW&c+Ls!dbRh`J1feULKlv(-%Z~t-rQH1b zHhqr#9Q5#)A!YhmT7puV;UEHCJkXK=sr^7P?|Nbi|u0 z-3107d+5Q4`6E>)Y(@#=NSR?`y!lgS^QwtxlYxJ3vSX^c!7JL!xZn#TnxpmW# zD0|XR;HKUGa&v->roiBSJ4%|}*eh%?p%$$DkJ@rZCKRvbUz8>?=)OdfCE0XB9$fJ- zMZ(dl(H;K)X@F=4W|~OKENr-8VRj( z(p44|FGiivAS;X_8)ZG=AFcEQp)MKQcPc0RR=2?0|Y439zsh9{Xbkg;kFy)#S42q73IraLRVr{Pw zu9X?Ev9%3lD_C@J{~G1Ow8bJ;zB~;9)mnzHYjt_DpLneHh@?jwlaIAMEt4BE?Q(+o z9S0bssWQKL#2@_98=5m_r;|L_uhUX zkHogKJlTtPX|0Y>UU;nO+=k&21D@aR(Y~zLK3Z)GV-S7sX%8L^di*Z4xG-gX0YsHi zc3!OPL4ec8ISK7r*hUMP;)B(>B72#;(lvO|4bSbwI5r1bL?R1xOi$uQKknQhnX|t= zm8k3W_DAk=>NaJu~97$S zFYkFU5PLTFD}~*`ytD6g{9T-NENHj-n0?H7ZuekVb#>gCdCYk&9{=zFyV}`7Dn#md z+k9S1qE#$PzPifiu4VU%G~#hjzQ2+Re;g^wYbge4_QY~LuhRD)h$f$@@GDo|;CA1Qzxm-?CM1r1W6046FW=1oah|o*bdkl|m zJ;G6>XZ^ws5WTBAZ1a+lKOGKe5#N0@EB!iw+0 zMN7L|iPKv~4DpPn{EI%9cv#g-$j@n5r^oO@F5`^#q!($y$oRI)d~}&rM2Tj!w%VBy zN|Jmrp1D%i?F>Oq8dhp5TD?#j@8!s_ibZR0*J`d7#>XESITP-^8J7wFs%(d0H|a|( zQELd;W@f&Un}VFb#VbMxw!+QA=Yi(39(4OBxoYFB<;$a56m`dQ z4|$(WDi6j8Y3*Vq#e+Sa`r;vSS9cJm;uSK+jz3>pk_lI8*F)8^aD8H|!dRE+`b=iE zz;D|#HpgbS<7XpQx_v_mFxM&BxO5^^SH+pbG zL~;6ez5wuK`AgL$Sefb|F4%wfcBb5l{c8sic2NN9D-5&_ZJ~)lv z?Ya8$V-cLDLtZx@AkeHKG)YUeC{JSXvDfcp;wzsz~`^0;i zNtT9kC3>e1ke?aU>lO86rc>8>6!IIbiy4aJ+fh8;_2B(dJJj2;Mo%1O;<)Z}#e|7}^XG_2I^xd`RQ;+HP1LRHH#1uBZj}adb zl(dw-M>OW#Q!>WM_36N6A7EK5n=p3(oVght3RCtb^ZjEc;cN&+$O$^u_+&P%8#j_T zpG5|CBL=J>K%$3#nY5y(o)#bpk;k^m+*n*4g}aq0V@Ur_A7l?j|7!% zb{Jdfs9abpaqEq}IgHI>tO6?DR2k=c^j*(oTRoO~ZsO@$rES++7q%2YWP8-<)urz) z+Dc=TikQoy!C0>CD`^K&GG;B4s-H&i))06^OB-+Yd18B?hMApfaNl{psfLnKmo#a-;2b1mbVQd*SA`@~g(EwQyx6 zXbC0b7}eFNvn9?yOBGp~R83A#PX3=n@&Ek8+pd?N0l7K~WPaw~8?X3D5v+TsYNR=L zv4a_pK#;_B!k%utqP;8N-RFzhx)NAU)qN-M)~YziacOq@;$}{DPW$-&{`RzdeD$$| zqtkSR@!=6Rhx6e(Kp+oTMtfi{b(Xu|&BOJtdft?~EyrAm84{mu`K zMMmRK3Ki8;ggr&ra>hzBnYp>8jjFPPs_ac0jkZVhsI20)9m`+vt%UB(hqsi9mlp`t z5Pw}rM`fgy&qn>?gSBd6+PFVd^XvmlAyy8gOsJ zP>8J1-tk(fd(&7LOe0z4b_mImFR-Q4jJD!G2?}Z&z01~So3kD0udj@;UmT>K(d&@? zk;_$%qgp{8mmneY%@OZKB|pIz^@Sq)#W!Gbx|`6WGRi}CH|N}yRddykoMj(ald}}2 zzhbHtJ6IgDHWt32Z%92Ze=~ek05)nVQwd&Y&fI@d>=D@1Y4!^3bi1~X zRw_e=r@1AbQ;;B zK4~d>$5`DL!-ci&M`sc7FDtKV!+hucFgRvAn%D%g2~KhEf_GHWfjUOl$V`0?02vBtonxWrKV+fk128rc>8scwYK6$%@VK^C#P6+J113GC1RpodH+G$GN9%bE z)0#wX`-eYrW11g@$ha{*Jb(+Ny7S=qG6i}>^!FNh@g_Nv=Exj(g-~o&51&o#s#xUR z>crTJ2*4?~*u3Ko625a`$63O~7ES|TI$Lq?a zH{U#ayB^O~gnBr5aEef8-ek8~j#jgzdx3UGnBvah=VLr|yo?7KtxemV_>U3LV2@|I z##C$|8E2*>F@2%|aXc|$9#)>-wgbD4{cX~Rj6JQP4q7z!{xB|a01;GX4~o8 zV8McYs1ROl^%R-3Idnk4s2`JuZHImkoOH9nVGBd2{bs{k?b|!iNqCI&#Ko6K|NH~7M(>r`RU-zb;S{M{x=RDr2G4ah4A5kY!&C# z6Yzi~Mj$?7pk2HX&gn^=jcK=n8#!+rGc>bvjyd>2HkrR9=~&-1)#7)#Q|}EgsH|69 zo-TWDrJdtQ_cR6HKi+t->fr3ix^%Qi3rN8$J528yJDjXPeJZxUve=RKE;=@!8jz}? zTu2?ws@juLEltG(1o8IEBQJ)(l+5?^t7_jxlzSh(L9_i~E^j&0=z9+-8ue&UiKEeU z;1HJF0#%N-daO~t(&#?sFhzaoPT<&xT%KB%yNdRjijR{12csi@Kp3xr3PnX-X`5Am zuDz=q6_!6_r0i6d_QAsyOk`)u4# z5S635W%UAcJEF~I_Od2opXJIo@9$hR%NTx4tFI?WC!!lhg3@ENEi^21gjx%EwwE4t zdh5s-PJd{7Xi+yjB}ct@(k*XpJ;k&7_$#xW=x88|wQb^iD_efu@xsHpXDyZa8AbD> z839hwg-mZ_(Hhb2qM(>eF%EAL?M|CC8-gR5z8awyahKS$4$GF$x5f*Yw0(I)4B1)k z#H1`y?a*HQl{tZLpAL>J*`1|SC{OJ<o23sE76J`F$vq8HDv^<*cwq{?{_Z#=nF$mxsPv}+eHw{K2 z^y!ZzzB1|2DKFPzO5*ceVu^mpXiFki5hd&R<<=WrRf(daZ$qzh?u z@Jo>y^(tu!!&%!$jrIqgkU3`anYnl4o)>vohuubc z6d0~5N)K*OWc;QA(MkGu4|I${`PO$bW~eiLZaB4VDqV4^JdpCPDHtqY*B?+)6qu0d z(aDZl^2Ce@PSGi}vBTQuN5oE9vv(rAeYw6ANW_@dJwn1J?>(%VvmB#S`6%^*fn+ za)3(dATf{WvQ99KzC;!dty(kZfhgzW&h_|E*r-%nhQv1Po)6WVcbHPEFyblYk%L;L zyvyaskNpf?&^I5DE1}QVVIv7Rba@Vt8`B=!L&hZcM;dy*`H`N4&Z8caFoiL-2JuGa z_~){Jqfnmj+5iuK>e|jv#0&qCL_BE!_Yd>&*9_u8mE?o)@TaSf03P16e_0B$i9Ql~ zJd=gfs_H3(1}+AS#i7Ge+?|(z%I$nYF-!FQ>h~(n`@?}j)6?y}& zMntE*&nM1nNBxYb%(H1ZJStGV@}%X{yIulPi~wIu?#z;DwqV*bm~Y;{GS*l1G%e06 zwi746qY(DPn-BdVc2=Z~nJGgutJ8Vyh9jK{5puVjR}0YQLMt7zval3tQb`Uu;rhbK zh64pynI+Se1slm$zfA=mWF&q6BEMR?p;*e+*OpGxthuY`R2D&LZRS%pWUg#7KQyV; zN~|EXVmsPaSgDj>lqmCKU1G&z^Q*FghD_!`<~K}OrcLo}`kPjKvnk7RQ7f1P1KkSC zw}T7k(p6gPWydn47JWuxNF@1^z`8}~EYnWZ-iAK2nJ!wC%VAc@(yN78tFn0`rPSw{ z$A>sd3^m8>BLr18o41;DfRn0LVwm%ck*%*ei z(tNNVe0nz^RWom1f-bYb{k*emCGXH*4{TY!@@{9(Yd(`(FW*r^y~>1AQ$wZz&)<~} zt`6#2(R;uYByuC31>$oc4N7Ygh7D_3n{B1v>c+@XT$Z@?Q+KK4AER1v1h9fMt{Os* zR`PW4UA$-t?u5@N^*^+I4BvdWE0Z*S^)n=#y9+WI?+gP4f)v&$9&H z7Cz#8XcdL@M0x;Xs}>5M#LY8vL8(tAzgNcr$<|j$44Y2!&3>_Wb>3)1)69Xfc$@E%T9Zrqrnzo^k^z&(z@Vv~y90TzbzNdlTiyn_Mo<^)@SPm$ zZDK(tEv za{2_N?oS!{ZCF0Rv0P_aC-pASa}IPjWXysE=Vdo_7*JA&=Jnb|s;E|WSodz`#1sA| zzpA|SPyHS)%=RybU=%tGmYI~@8%~gvXP?;K5ws%WcBl4Dy94I%c z0qGhnA?YoH2)=IeTGf4=g2wr2&BvTBuq3a(hvKP-!LT<-vesH8^^_M)iuu0G+j4Z= z`8xLY9`0w+Y_OP|{uNmPqoouZHR71^DluHHb+Y+1p3>UIBY#VU+u3$Ciwi+d!|`hL z;&6N7H=E=$!2-Vs^vo9h%+}Zzna8)ouoSj!2R~cFUM+9KlQQ!4fsJwaXlZ>UW@1=A z7*vPpX1h{@606a+1+AaI8vqym4rUE6>W&2C+PYKQw*OrL^0ys}I=B0CCHM&LG|fU$ zLv(&O_(q;ST}16mp&HsNT0Z}BVR5MCb7Gugy;Y}UYr))&dvgWQd9s0e`l&g7jT!Q!sy9CTfyAYyveLp{4pM+QcX?tKrXEHF75RP?vi5`Gn2pYx zcAAmXS2IiJYtd>BY)nW)_v(2nWFutIxT(YOLb&${e>9Gn!&hdZK&R z*sNzyoA0p%aPv}IgbCG2K1;K<7y71=-C^w*GVK($`Ch+yROT(N`WQ-7eQlPtidA&V z7qec5p5z>-&k1HDI#UaK*$fD~4_mqz?Bpqo0uc$*K0JL67}h@-xCLe31Q8*G*|xyK z&t0f#z^{%QZjLojY&M7BSVB8Q-{mnA5F5w#{li_@L+oB$#)X^KEnzhy^JOaQBXe9T zJ!K6pJ1;U~N3aU>>dMO)QT^w_wQqG4?T_$789aOR+Tz)3QJq*(tnVLCpN%19ZbPC- zs)#xTo}3h`&57CQjKVV4u54_-H|NCH6No5^*cuIwm7w}c^+CyZu(IJ62ZN#QqYBED z`)m<3UNG?X7<_Gxk1z}r!r%?EbQL_ZMLI}z_#+29%^I?sTwg8njfpJ^D=CW^)4sq! zccb9RZ?#G#b}D(g4_46#1tZio75Lg;TWM02=z02&GOrmObg@Au;%~lgvaIqX8e_CX zil)FBIZhI5@xutg zNF1!awZ}X7#`C=iyq=YhB}dMLVk$yD*Y=GZ4y&()xVegy>B}oOQyD1Nd=d!-BXEVg zlF6j7HM|3GDqrCqN;UL-l3is<{L*++5Uwt%vPOM!QT$zmh!9)ts>1=Fd9SDz@4Rdls^zc?|3+~CUT|bdW+GS8;fvLTC)9s z5E99)QN`(Fu@>Cw-NPl$8Y2!tEpeGsETYfbUeSI`fDEe7uTC~K@QO0s6wt-ePI0I z0rfn5b~!tmTqLcu`KR_D3);&??{So35{u(dO_)iZ)k>Q-*vUD*g(cBYy)*1Gq+gWR z=phpKJk#Ok6BTEax(>LW&+xnX)%aj9vuWrbmysR7p%1faA zhz{!`#nx-xS8385ZYXpKtu{AvKeT)K&_#+OLUg%i_z22dNx_e>U{f|8J#544U-|gl zDr>m^d&c!o1oP+lz<-#ZkGgik=3<)(1caYmh5DV_`9u7TJwxM3D2|wVt-w{<@-k>N zMn8KDPif7RyS}${osMQ{SpmDDSD!GmSFImxn+`Pgj|T>=I_$TNbL<^$`uV=ysGaLz z1>|e!QL8z4eLw12XV5xP-Rlo*4AE}RZ2o{njo*o@;uR~2lTWw#7Go2)J?UGfo*#^1 z8!JD)d0!@zv7oK1ru4iTlj7+td9=Hr<-VLf!qS{pRa5t>(fQehj;8 zmGy(fKDhLD*6%D_D;~&76jXT_%+Vuf)9b=luDQjcIXHN}b)W8=jOkXy36OjrzAaVk z`^FPcH95qR7F9LNF~UY#=Y8+Z>Y)1jVb6R@m$FWqHy$*lV~iqA7@uPjWnb$B-F(1% z+wuv$-GI|%NC7J*0i3wB$)hk?BROwm0~1WK#cp>hVGM2zv5IlR#4q*;L|R%2SP!BD zA8|+B(zHon(^ra_1A6+Mv1IG*k>EkZpVYKRu|rx&%BSV*QBjS z9DOMO7_`JLV+lnc z5LNZ{IYB2nbS`wD2CfKx$&XxK)ppz63vY5(D?@)uQQ%g@GcHF>E{C2zrZp!xWcWB5 z40Wc#0x&^D34TMIsB_9`j>^!SfBbWmNegVbHm#B8bM%3S$eTlztdSxZD3(OZg}eD` z1uQ!r2~rAu7VA+HYz-BefQ>bqw&d{r3=EC)^*Xd2r&M7JAeg8W5@~i}ZNvmJ8)P-5 z73a`3AIeE0mXi^>6j{~}s@s!F($!|~V63&D!1%8VQs*JJJ}(MZ|L>gFOQFr{p@9O0}`UvrQYbv zU>?=+JPdwq^y7i0GyBWIAIk3b6~?_AoSF|SX>-_oAG$5Z3C!7W;=YC}drjGmgw%iI zS#B}LaK)R?AML7wRgR%fgZWung!g)YVE)v*{SR_BAY9--%*|gnXLHf4yr?fJAS(|j zj0cp~lnDrasJ>ytSd#l$|KY&a`qB3nFKQ=tCh(#sXIt=}QV{iUoNT4xtu`L0IODHY zZyszfckJd=Az0|VsP!IxQH5t~C66IXonHbeS1~o|>1#ghy!k zamvMa@4pMx*wtx(PBYaf3i4-yzs&*<4Lgxi>8z9ebs)uN9<7(fvZ*k{xqVVGGjFO@ z?{2OnzmZ=Q@-OvFEK1U4;U`Jq7@)EJj7nolC}vu4Hl*_##y zvj{?y6tzDXL|GoV8{1*lhto;Bz^~hbl#^zdfXTk+d7RGolz{MSDV{GNnm?|AN&XZa zi!+Z+{jmu=Aw>}EQ|Cs@r+|IRmt3U08(+L6n;R*QNqgJKBVcc0+*M;uzgN_P89%*Q zbX-KH;buTcZB`bi^J7NN`je_v6^!FoXqZ9>K~)xR9{e75<3A{VEOt$wSP}W7lsNOPpp_Gk!ZsiEtaA&A&x&3s(HoVoxK1 z`J;LrtJCs$0(kQROQVM6_FFcjB+|svf(;c(W8(DC`MQJff~8+Jqtqd>3Q8l(;C1Ks z_hP_Q-f2I1^4O0xnebz@q`@sHxxtif!Z;t%jU10;Fy$BJd~a$N8oT2nVqUf<4ntY{v^^%TZ~6T|g{rDOAzH*p1YwSN6r+Q5N< zLvDkEfkB==NJ98ukGutT>*pgeSJ-f*0r!&tKZs`^>B&t6DN z|7+dZ&$gV-bexk4JIm=*$k~@bcvgt(BtXbtFX7*9`Ar^>xJ$MP_pCUsR6r#4Q_4>n zr@xu}wW99lCVD`kK+NU*x0aEg73B&JbxzBEmkK2GlI=Td8p~W?0Yd+yeSfbO1QK(} zwh;rhjTrjBwe2s7Kmsq>E?`?+00{iMUB7Jc+HVZl7CCO7)2g%buG1#qcLjOtY@2>s z#ZPkAZWZvmQUHhn*~5S(UZ-8aeT)b&Qu+H`{gm=oAN#p#6-d-2?GU(+IRZqT-!>qr zKtlhEEuMZiPF~xRW5*Hc3;)i5F`pW!b_n56`WrSg)!MxQGinA0w@wP^yPlJ%|}3P zOM?6|C{A}RzP{t+0MdZ#-W6e-qs#?x6q`1D|K&P?agf}<1dj7&U@mDJz&McUuZH71 zWiEi@sb#Ik>73Q?K4Tl8%*EZOHmI_LOTqyDl1wmO4Tc0rRW5*{>wEADXv_G_bQu&N zw)eimpbXeDa@ej2;~Zr!fP*4vY?bUstkgDEnC)z~SW2Q2CspoC@ey zb4e>X-Id_imF#K+$Qgk6vVc&EM&)v9T>#Mnr*4P*zY(3*v;4Y}T@`q*i0Hhod`U>B zlgz)aWLF-+>q9zEu?t|rgb>*LwSN#WCVHVOVgj}C+Z8$)FeY5_>ti}ku?t{oOl_%F z1KHu=C9aAIWODJ6wglYaemwsJkU*++0Yuazr}YOAfmG`Ph>Z5{1f06<-w|nRUlq}x$h`m~k}&uKh(M}! z0Yo&mtKgtxBsRmVA_AERxt0}Sn*9MpAl146A_0z}_opNA(`t#+lL&rY$*$1mzajc7 zPkm;8y}#}Oax{P;=zn;jD}3}%H=O--CA;ohpAY9R(Z8~HKf}tu?w+gA1+avc_(y00 zu$(UZIo%re*Olx#0hnI;d)x&q5i}N%1D;D-%<1lpzpiB0X2)wl0jbUfkig8YivC&) z1#BtVPM1Y;YAM%GRsdT{jQcg9oTJbMu$UK8ahxs!KD88JEN&i`#ByE?e@R;b#$w`g zbu8y8bO9_PIVIb_tOd9O$@pFp3t(7!eOm$UK-@uBhXPui3m`GTs~P!aDZog`gD;H) zR9tmQI{`+55_TOVpwzhl5^)RbTH@X12)X|>PqALH*)@mrhu;waGG2v?JSaClW2eE{m$M|InTjg(nf%jp~9IUft(fmD_}c&?_6ar zfJ2$Q;f?aYaRARf(_~!&2WZ!RNf^Lsa`^nK!2qqw1yH1-OpSrIjAei-f4kJP=z%9( zPi^I2vGesmyTF#wQF28XR}ar>inLu{g0zf+kC(v#GHSk-WxTGuA`FnKT);B!@!&EE`{Td*Q;PQUlj%@RW5+S z*T``ewEO%4Q03x21LOz(TAgH|?TRQss&WAoYnv@%psk{`{W2&(hJV*W5!rJ^6d+Z( z0E&+k>WiRJ*!Erq1;_;FwNS_oT@eLHRW5*HdupxxIlx!^I&}H(R1EX*SrmV#gZ>V< zfbRh&S^smabcGxla0Gg10wfM#!M{Q-;JfFja{(mKpMxvJK_b}!sBgbY4Kn?V-Z7ER@;O7?i{G5gP z>G97N_WX4hQ;eh_< z9JMZh=spqi{ooHk0;$#o5S`t}3fPjK(_ax0sPORG zmL$q}eMsjib^%Oh_kjV%^n~e(nEp_O6L5!n#CCm5=P7mpOlP-J0Pb+a>{rDEGG4n@ hhr{6c1CT(f1riYy^l66A0q{qY3k(d37aZ`f{|EOtqwoL# literal 0 HcmV?d00001 diff --git a/extras/lh_bench_23/tables/table14-part1.csv b/extras/lh_bench_23/tables/table14-part1.csv new file mode 100644 index 000000000..a097532e3 --- /dev/null +++ b/extras/lh_bench_23/tables/table14-part1.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_v,s_p,c_p,g +0,0.00015287245911193973,0.00010244420879692456,5.701804944047695e-06,131.87354078018697,3.1436816070190436e-05,64.86280173199475,64.14679157813721,997.1307561193358 +1,0.0006917569524690991,0.0004428380604103019,2.540962411572222e-05,68.4720191281346,9.42792786741986e-05,33.38326131051351,32.81465915127868,490.92487156828173 +2,0.0030981326270356786,0.0018974460360321244,0.00010718483116568849,33.461112615453715,0.00022789575898341058,16.053854716894566,15.602425570742932,222.8638269365544 +3,0.013721769310852954,0.008101888077206186,0.0004255769417049491,15.198222322725028,0.0003664344617706678,7.064240906094766,6.707006911909647,90.62109137834351 +4,0.05915981022842837,0.034050091187079676,0.001600817741486654,6.320848112146725,0.00014478892398732063,2.746344166794711,2.4693798899099697,31.335057045083516 +5,0.23078124616541104,0.12918608326642272,0.005568820929143852,2.274488527118306,-0.0005731348830417141,0.8546973873853968,0.6659329364925008,8.134786865601695 +6,0.5517722225901678,0.27164625865340714,0.01002324771919923,0.3901999927214852,-0.0003062707790024255,0.11386287962380881,0.05978038012395867,0.9057095918940038 +7,0.350710705459186,0.13024518634017762,0.0030097514678153223,0.03538233025460973,-3.189051747450462e-05,0.009059784104510277,0.00331784676447431,0.08419882231397229 +8,0.12116571740510448,0.03152817955811504,0.0003774489567551988,0.0023978725250082887,-2.7212872822323428e-06,0.0005852689571532032,0.00017734627513034333,0.008114298655058918 +9,0.02007661343791621,0.003089686879163111,1.3425066324357693e-05,5.645029865879282e-05,-1.009573276531744e-07,1.4094927426920052e-05,4.729604168208169e-06,0.0003893466314738704 +10,0.00034831969426205625,1.8126120451104446e-05,1.3857168200479219e-08,1.0976694347403099e-07,-1.9538726216645008e-10,4.266251710132014e-08,3.467022512797678e-08,1.3144918135419134e-06 diff --git a/extras/lh_bench_23/tables/table15-part1.csv b/extras/lh_bench_23/tables/table15-part1.csv new file mode 100644 index 000000000..26e73cb1b --- /dev/null +++ b/extras/lh_bench_23/tables/table15-part1.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_p,c_p,b_p,g +0,0.000159782374311217,0.00010699241911535113,6.009015496846315e-06,139.13928062954858,68.49731978436135,66.91697983928132,57.42568592704109,996.6675145065224 +1,0.0007178657639104188,0.0004592942706299979,2.6568708091322922e-05,71.68226745584901,34.989734427967946,33.836111498021616,28.320322848276696,487.9438171573828 +2,0.0031907023731048067,0.0019531589653931118,0.00011115555132507422,34.72298924611498,16.685881942626345,15.870039212653651,12.89214786058769,220.04499947199793 +3,0.0140232686578052,0.008274868945261757,0.00043743669108779867,15.611573096850242,7.271850237393598,6.721668446807849,5.257516676590805,88.7642975497294 +4,0.06001919955770306,0.03451917692499591,0.0016295699869199906,6.4149915243002935,2.794346511134117,2.448361021098347,1.813137812920204,30.390653078319012 +5,0.2324397382646147,0.12999889623824362,0.005609993691256854,2.2770541079861912,0.8571489068450455,0.6671721948337064,0.45050945142907206,7.787634909871445 +6,0.5499296886621222,0.27035225414735103,0.009959484979999919,0.3852489055042383,0.11229965666994945,0.06446333792031315,0.03727981250433008,0.852656883395241 +7,0.3462202170026868,0.12832721263591973,0.0029571097572013033,0.03460464974152799,0.008843196612568945,0.004015330303851035,0.0021060685257447464,0.07889787366674228 +8,0.11867951049731149,0.03081193356732983,0.0003676360060554282,0.0023218852746459554,0.0005641707476070221,0.00023861193568355801,0.00012078286516159336,0.007639901954040944 +9,0.019485952078180744,0.0029916486471481363,1.2941610344354708e-05,5.2561756934419664e-05,1.2683117277967177e-05,5.826485625318874e-06,3.040799711776502e-06,0.00037059333306847114 +10,0.000333151299898071,1.7424361032069554e-05,1.0526658121963792e-08,5.649526949817055e-08,2.021241819112724e-08,1.4645616584749484e-08,7.723841186086722e-09,1.2675973256045495e-06 diff --git a/extras/lh_bench_23/tables/table_FFNS-1_iterate-exact.csv b/extras/lh_bench_23/tables/table_FFNS-1_iterate-exact.csv new file mode 100644 index 000000000..aa9194389 --- /dev/null +++ b/extras/lh_bench_23/tables/table_FFNS-1_iterate-exact.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_v,s_p,c_p,g +0,0.0001061603548957915,6.23275472893752e-05,4.243957986065169e-06,135.94488325163329,-1.3010426069826054e-24,66.89456720413183,66.1759773366227,1147.8382214801056 +1,0.0005417657995652307,0.0003171899670480823,1.924091431171264e-05,68.36483648465217,-2.803667050041078e-16,33.326476266126036,32.75582146241892,538.7782369295227 +2,0.002687028982050863,0.0015677446978947405,8.357487370497726e-05,32.717724902071076,-1.8013338745430897e-16,15.679390309776986,15.22631846481875,235.17837712758714 +3,0.012841192800483271,0.007455766650175842,0.0003491097699833948,14.740323158751147,-1.3713861343986286e-16,6.8326719755594665,6.474102527297386,92.82524428423069 +4,0.05792559347182856,0.03333664735103119,0.0014161667774037975,6.162724959898692,-3.8507059009079235e-17,2.664880702993033,2.3867931368899464,31.488337782656565 +5,0.2302608560372903,0.12928105161452907,0.005325089076559043,2.252020696315615,3.390856095543345e-17,0.8418976521783023,0.6521710660642149,8.103188280181767 +6,0.5545223543069604,0.2733637481554953,0.010011414114518028,0.39337625615206745,1.113642593562985e-17,0.11490132195877217,0.06035880709178404,0.8987461285947349 +7,0.3539304069655586,0.13157575236540345,0.0030361828873799843,0.035871126114853706,7.415413557939977e-18,0.009214748678713814,0.0034006624187515656,0.08346281894419927 +8,0.12270649770189059,0.03196706036819016,0.00038269696480829947,0.0024236558222823206,2.2470104466262916e-18,0.0005898279188058254,0.00017515898522900972,0.008048879945233074 +9,0.020428258680076757,0.003148466517802246,1.3695745989556196e-05,5.5812869364637646e-05,6.435968613004415e-19,1.354956993547647e-05,3.978271511150513e-06,0.00038707753770232445 +10,0.0003581429894790383,1.8653182735031733e-05,1.432179062713306e-08,1.0462935965324338e-07,1.8140662449013975e-21,3.9923215185189465e-08,3.166189618573618e-08,1.312069774579141e-06 diff --git a/extras/lh_bench_23/tables/table_FFNS-1_truncated.csv b/extras/lh_bench_23/tables/table_FFNS-1_truncated.csv new file mode 100644 index 000000000..f715f873a --- /dev/null +++ b/extras/lh_bench_23/tables/table_FFNS-1_truncated.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_v,s_p,c_p,g +0,0.00010723462916228652,6.304516731093268e-05,4.164754964544373e-06,144.7074897533197,-5.960464476584964e-15,71.2774049623324,70.55983828629708,1082.3435303578935 +1,0.0005529404443077009,0.0003239489663496582,1.9582315470878136e-05,71.99355059408438,-6.08338701678715e-16,35.14205400224067,34.57221241418926,519.0923112686206 +2,0.002752823008775745,0.0016061384086087883,8.692003845839459e-05,34.08769374774182,-1.3183035262390176e-15,16.36536133478021,15.912941478487049,230.44661277831844 +3,0.013127888818741155,0.007618165274080762,0.000364589152972101,15.1988585225735,5.422061193975909e-16,7.062798109064177,6.704776954280582,92.07354002420296 +4,0.05883095627749258,0.033827800671777576,0.001459631770358389,6.2914783388055495,-3.6956091097739395e-16,2.730169759944633,2.4526358335997442,31.462899314870818 +5,0.23167881712726682,0.12994135536864662,0.005373644291797339,2.274599763663608,-4.8956523416453433e-17,0.8543182778232005,0.66530007595447,8.117887458641773 +6,0.5522575156446576,0.27202612064233395,0.00995515975019518,0.39182409193767676,2.2212724689685632e-17,0.11477319000703984,0.06065996190862552,0.8993713711837812 +7,0.35089903645815546,0.1303562018256726,0.0030049658601700546,0.0354244566460661,2.892217229418544e-18,0.009089472631843735,0.0033407274714736626,0.08337894062943672 +8,0.12131178404157113,0.03157689188696171,0.0003775209180593767,0.002373517635653355,2.3288897822325384e-18,0.00057357538258912,0.00016478380969987654,0.008036211750807088 +9,0.020124308519381684,0.003098254604289683,1.3453716672555602e-05,5.252415879933615e-05,1.266815138828743e-19,1.2165349290370563e-05,2.7674656796985234e-06,0.0003868979493775284 +10,0.00035004483153421116,1.8218743777857735e-05,1.3974787856675872e-08,4.5802256991335265e-08,1.2083432589668223e-20,1.0836648105239018e-08,2.7932619550552214e-09,1.3200600133284349e-06 diff --git a/extras/lh_bench_23/tables/table_FFNS-2_iterate-exact.csv b/extras/lh_bench_23/tables/table_FFNS-2_iterate-exact.csv new file mode 100644 index 000000000..c90a657b8 --- /dev/null +++ b/extras/lh_bench_23/tables/table_FFNS-2_iterate-exact.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_v,s_p,c_p,g +0,0.00015287245911193973,0.00010244420879692456,5.701804950008159e-06,131.87354078018686,3.1436816070190436e-05,64.86280173199472,64.14679157813718,997.1307561193353 +1,0.00069175695246707,0.0004428380604096013,2.5409624115590328e-05,68.47201912813458,9.427927867448377e-05,33.38326131051349,32.81465915127866,490.9248715682815 +2,0.0030981326270347925,0.0018974460360332897,0.00010718483116562811,33.46111261545371,0.00022789575898237165,16.05385471689456,15.602425570742922,222.8638269365543 +3,0.013721769310853001,0.008101888077207107,0.00042557694170455466,15.198222322725023,0.0003664344617713608,7.064240906094763,6.7070069119096445,90.62109137834348 +4,0.0591598102284284,0.03405009118707939,0.0016008177414868765,6.320848112146719,0.00014478892398720895,2.7463441667947093,2.4693798899099675,31.33505704508351 +5,0.23078124616541115,0.12918608326642275,0.005568820929143788,2.274488527118306,-0.0005731348830417624,0.8546973873853969,0.6659329364925008,8.134786865601694 +6,0.5517722225901677,0.2716462586534072,0.010023247719199276,0.39019999272148476,-0.0003062707790024365,0.11386287962380857,0.059780380123958435,0.9057095918940035 +7,0.3507107054591861,0.1302451863401776,0.003009751467815323,0.035382330254609344,-3.1890517474502425e-05,0.009059784104510091,0.003317846764474124,0.08419882231397235 +8,0.12116571740510446,0.03152817955811504,0.0003774489567551988,0.002397872525008188,-2.7212872822324266e-06,0.0005852689571531542,0.00017734627513029414,0.00811429865505891 +9,0.020076613437916207,0.003089686879163111,1.342506632435769e-05,5.6450298658805325e-05,-1.009573276531752e-07,1.4094927426926308e-05,4.729604168214425e-06,0.0003893466314738745 +10,0.0003483196942620561,1.812612045110442e-05,1.3857168200479224e-08,1.097669434718655e-07,-1.9538726217870197e-10,4.266251710024964e-08,3.4670225126906276e-08,1.3144918135418981e-06 diff --git a/extras/lh_bench_23/tables/table_FFNS-2_truncated.csv b/extras/lh_bench_23/tables/table_FFNS-2_truncated.csv new file mode 100644 index 000000000..4a30a0d0a --- /dev/null +++ b/extras/lh_bench_23/tables/table_FFNS-2_truncated.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_v,s_p,c_p,g +0,0.00015464892296731592,0.00010386845929324279,5.622136690381462e-06,133.5008556575877,3.230329199268242e-05,65.67708705995717,64.9614951356641,957.8459618822479 +1,0.000705761751535839,0.0004544718539811671,2.552290008851311e-05,69.0459315375376,0.00010257666378171392,33.67072527472724,33.10245592445913,481.395736551108 +2,0.0031543548925255615,0.0019427658309667177,0.0001089583218359887,33.63400688767619,0.00025888450199084177,16.140738848131477,15.689576595242569,221.1108702725517 +3,0.013871461518441982,0.00821362657668037,0.00043455283477972126,15.247894082263796,0.0004316495749325127,7.089499957980763,6.732485313205018,90.43515209072363 +4,0.05939964914027976,0.034196408019453645,0.0016281518752570255,6.3362000014014255,0.00018796981996899924,2.75443288697,2.477658630817675,31.34333829821278 +5,0.2308928793883309,0.12918385023233087,0.005610278860597694,2.2776538021950508,-0.000664249033788116,0.8565598999207122,0.6679632514950151,8.141202826783472 +6,0.5512875337070124,0.27134247402403655,0.010026111044900999,0.38992719563912914,-0.00036314888983881395,0.1138207754296992,0.05981844415766429,0.9061993666236493 +7,0.3501501361492662,0.13001356714644208,0.003005291520931824,0.0353162398653188,-3.7948403987817344e-05,0.009041931769499358,0.0033124999482985174,0.08421298934125289 +8,0.12089891642500451,0.031452150037026866,0.0003765528652237452,0.0023858872242725794,-3.2484391630543913e-06,0.0005806863423718898,0.00017393403039317015,0.008113446103398255 +9,0.02001562863727675,0.003079462568012769,1.3378254744689383e-05,5.423860954782834e-05,-1.2134014422699058e-07,1.3026681982729941e-05,3.697431328199803e-06,0.00038922380774916254 +10,0.00034657115630683396,1.803163500131224e-05,1.377129575740517e-08,5.132838245453915e-08,-2.379670148646283e-10,1.3462540042524917e-08,5.5180040543152174e-09,1.3143045886089883e-06 diff --git a/extras/lh_bench_23/tables/table_FFNS-3_iterate-exact.csv b/extras/lh_bench_23/tables/table_FFNS-3_iterate-exact.csv new file mode 100644 index 000000000..312a0139c --- /dev/null +++ b/extras/lh_bench_23/tables/table_FFNS-3_iterate-exact.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_v,s_p,c_p,g +0,9.836966763886141e-05,4.5170742957375996e-05,7.5012328115190414e-06,148.84799237885335,-2.910510638420082e-05,73.35205515462158,72.63743281068673,1084.619419631402 +1,0.0005640468145243254,0.00030894671096854564,3.073021905703312e-05,71.89461934475517,-4.673850737514722e-05,35.09609129818501,34.52859011025279,503.5885387790783 +2,0.0028945500676357703,0.0016810059147198179,0.00012301844981643713,33.85784622588853,-3.576027917521773e-06,16.25335183240206,15.802791260701232,222.82008299478002 +3,0.013633373064192496,0.007983215957929687,0.0004727422596436446,15.18190430761921,0.00021123185549078844,7.057102726770337,6.700536655532829,90.22155735168695 +4,0.05956724448832024,0.03438239502080433,0.0017231472128767477,6.300657024758889,0.00039314366013802556,2.7376273069860146,2.461131322708324,31.33586645434436 +5,0.2312988676321237,0.1296171473701861,0.005764529760983026,2.266845426007164,-0.00019644172893536565,0.85223443579442,0.6637194063930979,8.153411502330735 +6,0.5513064130916566,0.27140173696369135,0.010084634312905192,0.38980785041340793,-0.0003181208486145095,0.11388551884287841,0.05985044225727633,0.9062273296258492 +7,0.350435004860364,0.13014939156487818,0.003014371134640736,0.035450376781638544,-3.840886663652588e-05,0.00910188797427251,0.0033625040119352944,0.0844438866160732 +8,0.1211157932395667,0.031518221573520404,0.0003778065281636942,0.00240854950195688,-3.3050615272961475e-06,0.000590651121445557,0.00018275868728082553,0.008158561478268737 +9,0.02007701303116419,0.003090021580448757,1.3437066675585028e-05,5.681843776186922e-05,-1.1797439429869178e-07,1.426872161058544e-05,4.900884840678453e-06,0.00039235288217883514 +10,0.00034849118995363597,1.813462901552704e-05,1.3838070181071031e-08,1.098165927081218e-07,-2.1739624242785753e-10,4.262671491267176e-08,3.462774080439957e-08,1.3275395881221502e-06 diff --git a/extras/lh_bench_23/tables/table_FFNS-3_truncated.csv b/extras/lh_bench_23/tables/table_FFNS-3_truncated.csv new file mode 100644 index 000000000..2af479512 --- /dev/null +++ b/extras/lh_bench_23/tables/table_FFNS-3_truncated.csv @@ -0,0 +1,12 @@ +,u_v,d_v,L_m,L_p,s_v,s_p,c_p,g +0,9.343544936160187e-05,3.97588703957356e-05,7.634774574396073e-06,149.2941807579001,-3.5112148919386776e-05,73.57549898868884,72.86111343997482,1094.9096593483566 +1,0.0005471412343189227,0.0002907014882532298,3.126654684783732e-05,72.02462076969448,-6.65807383351694e-05,35.161356463659104,34.59404352385236,502.66814204097983 +2,0.002860229680268774,0.0016435696614229855,0.0001250321221518455,33.851910501447826,-4.4612311751533015e-05,16.25057461444312,15.800163462117418,221.92343864456535 +3,0.013610087080486177,0.00795365036709451,0.00048003091119545,15.159194026054355,0.00017475522591764659,7.045913097763293,6.689463282492342,89.97002152475457 +4,0.059618653451713306,0.03442582573289902,0.0017449527633395375,6.292121369891762,0.0004306457612423186,2.7335965648161547,2.457180790439582,31.299425909077453 +5,0.2313135880726135,0.12965308150200883,0.005802386394720998,2.2653807925410363,-0.0001265579405988536,0.8517371085580833,0.6632490854010611,8.152997034692607 +6,0.5512372240903152,0.2713868904410041,0.010100355232325945,0.3898481360803727,-0.0003222658041364934,0.11390490344974787,0.05984920401442433,0.9070889105845987 +7,0.35060974087052527,0.13023248263157344,0.0030183456887526304,0.03547319264938169,-3.99386992765339e-05,0.009104957227957185,0.0033594667088998804,0.08458842159263354 +8,0.12124915825634185,0.031558328219426696,0.00037847824987194986,0.0024032844752700715,-3.4419617890271927e-06,0.0005869941348835454,0.00017842340253973495,0.008174904794978325 +9,0.02011332077796066,0.0030962001697032305,1.3469938870202546e-05,5.459642840965752e-05,-1.22113552126173e-07,1.3122645783811846e-05,3.7325652398707082e-06,0.0003931456259688344 +10,0.00034957384653626496,1.8192571716122362e-05,1.38785628504736e-08,5.0388199511750236e-08,-2.2288232162085576e-10,1.2854620431865581e-08,4.825330555106835e-09,1.3296138258473455e-06 diff --git a/extras/lh_bench_23/utils.py b/extras/lh_bench_23/utils.py index dc83a2c7e..50033ad15 100644 --- a/extras/lh_bench_23/utils.py +++ b/extras/lh_bench_23/utils.py @@ -102,13 +102,21 @@ def rotate_lha_to_evol(df: pd.DataFrame, scheme: str) -> pd.DataFrame: def load_n3lo_tables( - n3lo_table_dir: pathlib.Path, scheme: str, approx: str, rotate_to_evol: bool = False + n3lo_table_dir: pathlib.Path, + scheme: str, + sv: str, + approx: str, + rotate_to_evol: bool = False, ) -> list: """Load the N3LO tables.""" dfs = [] + n3lo_table_dir = n3lo_table_dir / "EKO" / f"N3LO_{approx}_{scheme}" for p in n3lo_table_dir.iterdir(): if scheme not in p.stem: continue + if sv not in p.stem: + continue + if approx in p.stem: table = pd.read_csv(p, index_col=0) table.rename(columns=LHA_LABELS_MAP, inplace=True) @@ -140,21 +148,11 @@ def load_msht( table_dir: pathlib.Path, scheme: str, approx: str, rotate_to_evol: bool = False ) -> list: """Load MSHT files.""" - - if scheme != "VFNS": - raise ValueError(f"{scheme} not provided by MSHT, comment it out") - APPROX_MAP = { - "FHMV": "Moch", - "MSHT": "Posterior", - } - fhmv_msht_table_dir = table_dir / f"{scheme}_{APPROX_MAP[approx]}_numbers" + fhmruvv_msht_table_dir = table_dir / "MSHT" / f"N3LO_{approx}_{scheme}" columns = lha_labels(scheme) - # columns.insert(0,'x') - # columns.insert(0,'Q') dfs = [] - - for p in fhmv_msht_table_dir.iterdir(): + for p in fhmruvv_msht_table_dir.iterdir(): data = np.loadtxt(p) data = pd.DataFrame(data[:, 2:], columns=columns) if rotate_to_evol: @@ -167,10 +165,13 @@ def compute_n3lo_avg_err(dfs: list) -> tuple: """Compute N3LO average and error.""" df_central = np.mean(dfs, axis=0) df_central = pd.DataFrame(df_central, columns=dfs[0].columns) - # TODO: improve errors. - df_std = np.std(dfs, axis=0) - df_std = pd.DataFrame(df_std, columns=dfs[0].columns) - return df_central, df_std + + # NOTE: here we compute the error as an envelope + up = np.max(dfs, axis=0) + dw = np.min(dfs, axis=0) + df_err = (up - dw) / 2 + df_err = pd.DataFrame(df_err, columns=dfs[0].columns) + return df_central, df_err def compute_n3lo_nnlo_diff(n3lo: tuple, nnlo: pd.DataFrame, rel_diff: bool) -> tuple: @@ -194,16 +195,18 @@ def plot_pdfs( ) -> None: """Absolute PDFs plots.""" - fig, axs = plt.subplots(2, 4, figsize=(15, 7)) + ncols = 2 + nrows = 4 + fig, axs = plt.subplots(nrows, ncols, figsize=(ncols * 5, nrows * 3.5)) xcut = 4 if use_linx else 0 xgrid = xgrid[xcut:] xscale = "linx" if use_linx else "logx" - plot_name = f"lh_n3lo_bench_{scheme}_{xscale}" + plot_name = f"n3lo_bench_{scheme}_{xscale}" plot_dir.mkdir(exist_ok=True) - fig.suptitle(f"{scheme}" + " $Q: \\sqrt{2} \\to 100 \\ GeV$") + fig.suptitle(f"{scheme}" + r", $\mu_{\rm f}^2 = 10^4 \ \mbox{GeV}^2$") # loop on PDFs for i, ax in enumerate( @@ -260,18 +263,23 @@ def plot_diff_to_nnlo( ) -> None: """Difference w.r.t NNLO PDFs plots.""" - fig, axs = plt.subplots(2, 4, figsize=(15, 7)) + ncols = 2 + nrows = 4 + fig, axs = plt.subplots(nrows, ncols, figsize=(ncols * 5, nrows * 3.5)) - xcut = 4 if use_linx else 0 - xgrid = xgrid[xcut:] + # cut away small- and large-x values, for plotting + smallx_cut = 4 if use_linx else 2 + largex_cut = -1 if not use_linx else None + xgrid = xgrid[smallx_cut:largex_cut] xscale = "linx" if use_linx else "logx" diff_type = "rel_diff" if rel_dff else "abs_diff" - plot_name = f"lh_n3lo_bench_{scheme}_{xscale}_{diff_type}" + plot_name = f"n3lo_bench_{scheme}_{xscale}_{diff_type}" diff_type = "Relative" if rel_dff else "Absolute" fig.suptitle( - f"{diff_type} difference to NNLO, {scheme}" + " $Q: \\sqrt{2} \\to 100 \\ GeV$" + f"{diff_type} difference to NNLO, {scheme}" + + r", $\mu_{\rm f}^2 = 10^4 \ \mbox{GeV}^2$" ) for i, ax in enumerate( @@ -282,22 +290,26 @@ def plot_diff_to_nnlo( # loop on n3lo for j, (tabs, approx_label) in enumerate(n3lo_dfs): central, err = tabs - ax.errorbar( + obj = ax.errorbar( xgrid, - central.values[xcut:, i], - yerr=err.values[xcut:, i], + central.values[smallx_cut:largex_cut, i], + yerr=err.values[smallx_cut:largex_cut, i], fmt=FMT_LIST[j], label=approx_label, capsize=5, ) - # ax.errorbar( - # xgrid, - # eko_4mom_diff.values[:, i], - # yerr=eko_4mom_diff_std.values[:, i], - # fmt="x", - # label="aN3LO EKO (4 moments)", - # capsize=5, - # ) + ax.plot( + xgrid, + central.values[smallx_cut:largex_cut, i], + color=obj[0].get_color(), + alpha=0.3, + ) + ax.fill_between( + xgrid, + (central - err).values[smallx_cut:largex_cut, i], + (central + err).values[smallx_cut:largex_cut, i], + alpha=0.2, + ) ax.hlines( 0, xgrid.min() - xgrid.min() / 3, diff --git a/extras/n3lo_bench/plot_msht.py b/extras/n3lo_bench/plot_msht.py index 8ddc92d2a..05702729b 100644 --- a/extras/n3lo_bench/plot_msht.py +++ b/extras/n3lo_bench/plot_msht.py @@ -15,7 +15,7 @@ n3lo_vars_dict = { "gg": 19, - "gq": 21, + "gq": 15, "qg": 15, "qq": 6, } diff --git a/extras/n3lo_bench/splitting_function_utils.py b/extras/n3lo_bench/splitting_function_utils.py index 6b32c86cc..66a516a5e 100644 --- a/extras/n3lo_bench/splitting_function_utils.py +++ b/extras/n3lo_bench/splitting_function_utils.py @@ -103,9 +103,7 @@ def compute_a_s(q2=None, xif2=1.0, nf=None, order=(4, 0)): ref = CouplingsInfo( alphas=0.1181, alphaem=0.007496, - scale=91.00, - max_num_flavs=6, - num_flavs_ref=5, + ref=(91.00, 5), ) sc = Couplings( couplings=ref, diff --git a/flake.lock b/flake.lock index 3146adf01..d243cec36 100644 --- a/flake.lock +++ b/flake.lock @@ -4,7 +4,9 @@ "inputs": { "flake-compat": "flake-compat", "nix": "nix", - "nixpkgs": "nixpkgs", + "nixpkgs": [ + "nixpkgs" + ], "pre-commit-hooks": "pre-commit-hooks" }, "locked": { @@ -37,19 +39,21 @@ "type": "github" } }, - "flake-compat_2": { - "flake": false, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "lastModified": 1715865404, + "narHash": "sha256-/GJvTdTpuDjNn84j82cU6bXztE0MSkdnTWClUCRub78=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8dc45382d5206bd292f9c2768b8058a8fd8311d9", "type": "github" }, "original": { - "owner": "edolstra", - "repo": "flake-compat", + "owner": "hercules-ci", + "repo": "flake-parts", "type": "github" } }, @@ -71,23 +75,6 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", - "type": "github" - }, - "original": { - "id": "flake-utils", - "type": "indirect" - } - }, "gitignore": { "inputs": { "nixpkgs": [ @@ -152,38 +139,30 @@ }, "nixpkgs": { "locked": { - "lastModified": 1678875422, - "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", + "lastModified": 1715787315, + "narHash": "sha256-cYApT0NXJfqBkKcci7D9Kr4CBYZKOQKDYA23q8XNuWg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", + "rev": "33d1e753c82ffc557b4a585c77de43d4c922ebb5", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-unstable", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-python": { - "inputs": { - "flake-compat": "flake-compat_2", - "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs_3" - }, + "nixpkgs-lib": { "locked": { - "lastModified": 1692934204, - "narHash": "sha256-dJG+DyQlWgeBEcCl9j3R5A4vcBnC2GLRacNeJgcZPo8=", - "owner": "cachix", - "repo": "nixpkgs-python", - "rev": "dfe9a33d0d9bd31650b69c36f8fff5f2d5342393", - "type": "github" + "lastModified": 1714640452, + "narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" }, "original": { - "owner": "cachix", - "repo": "nixpkgs-python", - "type": "github" + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" } }, "nixpkgs-regression": { @@ -220,32 +199,16 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1693183237, - "narHash": "sha256-c7OtyBkZ/vZE/WosBpRGRtkbWZjDHGJP7fg1FyB9Dsc=", + "lastModified": 1716330097, + "narHash": "sha256-8BO3B7e3BiyIDsaKA0tY8O88rClYRTjvAp66y+VBUeU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ea5234e7073d5f44728c499192544a84244bf35a", + "rev": "5710852ba686cc1fd0d3b8e22b3117d43ba374c2", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1685974512, - "narHash": "sha256-WLPHpe96RbPRO9iDtCxgsYkadTheRq7wqXWdGpR6g7w=", - "owner": "domenkozar", - "repo": "nixpkgs", - "rev": "1102477695918daba466123cc2ef694ed3a49939", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "cpython-moduralize", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -281,9 +244,8 @@ "root": { "inputs": { "devenv": "devenv", - "nixpkgs": "nixpkgs_2", - "nixpkgs-python": "nixpkgs-python", - "systems": "systems_3" + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs_2" } }, "systems": { @@ -300,36 +262,6 @@ "repo": "default", "type": "github" } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 28ea23292..28cacfc7c 100644 --- a/flake.nix +++ b/flake.nix @@ -1,46 +1,48 @@ { inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; - systems.url = "github:nix-systems/default"; - devenv.url = "github:cachix/devenv"; - nixpkgs-python.url = "github:cachix/nixpkgs-python"; - }; - - nixConfig = { - extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="; - extra-substituters = "https://devenv.cachix.org"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + devenv = { + url = "github:cachix/devenv"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + flake-parts.url = "github:hercules-ci/flake-parts"; }; outputs = { self, nixpkgs, devenv, - systems, + flake-parts, ... - } @ inputs: let - forEachSystem = nixpkgs.lib.genAttrs (import systems); - in { - devShells = - forEachSystem - (system: let - pkgs = nixpkgs.legacyPackages.${system}; - in { - default = devenv.lib.mkShell { - inherit inputs pkgs; - modules = [ - { - languages.python = { + } @ inputs: + flake-parts.lib.mkFlake {inherit inputs;} { + imports = [inputs.devenv.flakeModule]; + systems = ["x86_64-linux" "aarch64-darwin"]; + + perSystem = {pkgs, ...}: { + devenv.shells.default = { + packages = with pkgs; [maturin poethepoet pre-commit stdenv.cc.cc.lib]; + + languages = { + python = { + enable = true; + poetry = { enable = true; - poetry = { + install = { enable = true; - install.enable = true; - install.allExtras = true; + allExtras = true; + groups = ["dev" "test"]; }; - version = "3.11"; }; - } - ]; + }; + rust.enable = true; + }; }; - }); + }; + }; + + nixConfig = { + extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="; + extra-substituters = "https://devenv.cachix.org"; }; } diff --git a/poetry.lock b/poetry.lock index b317d6d7d..84e9082a9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. [[package]] name = "alabaster" -version = "0.7.13" -description = "A configurable sidebar-enabled Sphinx theme" +version = "0.7.16" +description = "A light, configurable Sphinx theme" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, - {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, + {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, + {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, ] [[package]] @@ -24,50 +24,46 @@ files = [ [[package]] name = "appnope" -version = "0.1.3" +version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, ] [[package]] name = "astroid" -version = "2.15.6" +version = "3.2.3" description = "An abstract syntax tree for Python with inference support." optional = false -python-versions = ">=3.7.2" +python-versions = ">=3.8.0" files = [ - {file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"}, - {file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"}, + {file = "astroid-3.2.3-py3-none-any.whl", hash = "sha256:3eae9ea67c11c858cdd2c91337d2e816bd019ac897ca07d7b346ac10105fceb3"}, + {file = "astroid-3.2.3.tar.gz", hash = "sha256:7099b5a60985529d8d46858befa103b82d0d05a5a5e8b816b5303ed96075e1d9"}, ] [package.dependencies] -lazy-object-proxy = ">=1.4.0" typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} -wrapt = [ - {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, - {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, -] [[package]] name = "asttokens" -version = "2.2.1" +version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false python-versions = "*" files = [ - {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, - {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, ] [package.dependencies] -six = "*" +six = ">=1.12.0" [package.extras] -test = ["astroid", "pytest"] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "asv" @@ -87,56 +83,46 @@ hg = ["python-hglib (>=1.5)"] [[package]] name = "attrs" -version = "23.1.0" +version = "23.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] +dev = ["attrs[tests]", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "babel" -version = "2.12.1" +version = "2.15.0" description = "Internationalization utilities" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, - {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, + {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, + {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -optional = false -python-versions = "*" -files = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "banana-hep" -version = "0.6.12" +version = "0.6.15" description = "Benchmark QCD physics" optional = true -python-versions = ">=3.8.0,<3.12" +python-versions = "<3.13,>=3.9.0" files = [ - {file = "banana_hep-0.6.12-py3-none-any.whl", hash = "sha256:3cb065926a774689f6dee606dde0453e4e856dc1372c99e12f6b54aca26c41dd"}, - {file = "banana_hep-0.6.12.tar.gz", hash = "sha256:0cf4a78f5affa5e1afe138ae6c9df5414deb9785901b585fcbdf6bbf531a1b9b"}, + {file = "banana_hep-0.6.15-py3-none-any.whl", hash = "sha256:556626b060c178903e1993b45f6778e619896fd6345c4c3948744977affc0bbf"}, + {file = "banana_hep-0.6.15.tar.gz", hash = "sha256:96069215af1d56f76d80e428c679d399b30ceb357875d29b583706826e144e45"}, ] [package.dependencies] @@ -144,40 +130,43 @@ appdirs = ">=1.4.4,<2.0.0" click = ">=8.0.3,<9.0.0" ipython = ">=8.1.0,<9.0.0" matplotlib = ">=3.5.1,<4.0.0" -numpy = ">=1.21.0,<2.0.0" -pandas = ">=1.3.5,<2.0.0" -pendulum = ">=2.1.2,<3.0.0" +numpy = ">=1.26.0,<2.0.0" +pandas = ">=2.1.4,<3.0.0" +pendulum = ">=3.0.0,<4.0.0" PyYAML = ">=6.0,<7.0" rich = ">=12.4.4,<13.0.0" SQLAlchemy = ">=1.4.29,<2.0.0" [[package]] name = "beautifulsoup4" -version = "4.12.2" +version = "4.12.3" description = "Screen-scraping library" optional = false python-versions = ">=3.6.0" files = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, ] [package.dependencies] soupsieve = ">1.2" [package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] html5lib = ["html5lib"] lxml = ["lxml"] [[package]] name = "bleach" -version = "6.0.0" +version = "6.1.0" description = "An easy safelist-based HTML-sanitizing tool." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, - {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, ] [package.dependencies] @@ -185,90 +174,78 @@ six = ">=1.9.0" webencodings = "*" [package.extras] -css = ["tinycss2 (>=1.1.0,<1.2)"] +css = ["tinycss2 (>=1.1.0,<1.3)"] [[package]] name = "certifi" -version = "2023.7.22" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] name = "cffi" -version = "1.15.1" +version = "1.16.0" description = "Foreign Function Interface for Python calling C code." optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, ] [package.dependencies] @@ -276,97 +253,112 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] name = "click" -version = "8.1.6" +version = "8.1.7" description = "Composable command line interface toolkit" optional = true python-versions = ">=3.7" files = [ - {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, - {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] @@ -385,22 +377,20 @@ files = [ [[package]] name = "comm" -version = "0.1.4" +version = "0.2.2" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "comm-0.1.4-py3-none-any.whl", hash = "sha256:6d52794cba11b36ed9860999cd10fd02d6b2eac177068fdd585e1e2f8a96e67a"}, - {file = "comm-0.1.4.tar.gz", hash = "sha256:354e40a59c9dd6db50c5cc6b4acc887d82e9603787f83b68c01a80a923984d15"}, + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, ] [package.dependencies] traitlets = ">=4" [package.extras] -lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"] test = ["pytest"] -typing = ["mypy (>=0.990)"] [[package]] name = "commonmark" @@ -418,121 +408,126 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "contourpy" -version = "1.1.0" +version = "1.2.1" description = "Python library for calculating contours of 2D quadrilateral grids" optional = true -python-versions = ">=3.8" -files = [ - {file = "contourpy-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:89f06eff3ce2f4b3eb24c1055a26981bffe4e7264acd86f15b97e40530b794bc"}, - {file = "contourpy-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dffcc2ddec1782dd2f2ce1ef16f070861af4fb78c69862ce0aab801495dda6a3"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25ae46595e22f93592d39a7eac3d638cda552c3e1160255258b695f7b58e5655"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17cfaf5ec9862bc93af1ec1f302457371c34e688fbd381f4035a06cd47324f48"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa"}, - {file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa"}, - {file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2"}, - {file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882"}, - {file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052cc634bf903c604ef1a00a5aa093c54f81a2612faedaa43295809ffdde885e"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9382a1c0bc46230fb881c36229bfa23d8c303b889b788b939365578d762b5c18"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a"}, - {file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e"}, - {file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256"}, - {file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed"}, - {file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62013a2cf68abc80dadfd2307299bfa8f5aa0dcaec5b2954caeb5fa094171103"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b6616375d7de55797d7a66ee7d087efe27f03d336c27cf1f32c02b8c1a5ac70"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f"}, - {file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1"}, - {file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4"}, - {file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9"}, - {file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f2931ed4741f98f74b410b16e5213f71dcccee67518970c42f64153ea9313b9"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30f511c05fab7f12e0b1b7730ebdc2ec8deedcfb505bc27eb570ff47c51a8f15"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a"}, - {file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002"}, - {file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a67259c2b493b00e5a4d0f7bfae51fb4b3371395e47d079a4446e9b0f4d70e76"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2b836d22bd2c7bb2700348e4521b25e077255ebb6ab68e351ab5aa91ca27e027"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084eaa568400cfaf7179b847ac871582199b1b44d5699198e9602ecbbb5f6104"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:911ff4fd53e26b019f898f32db0d4956c9d227d51338fb3b03ec72ff0084ee5f"}, - {file = "contourpy-1.1.0.tar.gz", hash = "sha256:e53046c3863828d21d531cc3b53786e6580eb1ba02477e8681009b6aa0870b21"}, +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, + {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, + {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, + {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, + {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, + {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, + {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, + {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, + {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, + {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, + {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, ] [package.dependencies] -numpy = ">=1.16" +numpy = ">=1.20" [package.extras] bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.2.0)", "types-Pillow"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "wurlitzer"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" -version = "7.3.0" +version = "7.6.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5"}, - {file = "coverage-7.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637"}, - {file = "coverage-7.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af"}, - {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1"}, - {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12"}, - {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689"}, - {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977"}, - {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51"}, - {file = "coverage-7.3.0-cp310-cp310-win32.whl", hash = "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527"}, - {file = "coverage-7.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1"}, - {file = "coverage-7.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f"}, - {file = "coverage-7.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d"}, - {file = "coverage-7.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd"}, - {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7"}, - {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a"}, - {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74"}, - {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214"}, - {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f"}, - {file = "coverage-7.3.0-cp311-cp311-win32.whl", hash = "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482"}, - {file = "coverage-7.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70"}, - {file = "coverage-7.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b"}, - {file = "coverage-7.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446"}, - {file = "coverage-7.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071"}, - {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe"}, - {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a"}, - {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873"}, - {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2"}, - {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b"}, - {file = "coverage-7.3.0-cp312-cp312-win32.whl", hash = "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321"}, - {file = "coverage-7.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479"}, - {file = "coverage-7.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1"}, - {file = "coverage-7.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd"}, - {file = "coverage-7.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e"}, - {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54"}, - {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254"}, - {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0"}, - {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84"}, - {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985"}, - {file = "coverage-7.3.0-cp38-cp38-win32.whl", hash = "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9"}, - {file = "coverage-7.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543"}, - {file = "coverage-7.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba"}, - {file = "coverage-7.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393"}, - {file = "coverage-7.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28"}, - {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95"}, - {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a"}, - {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34"}, - {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e"}, - {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54"}, - {file = "coverage-7.3.0-cp39-cp39-win32.whl", hash = "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3"}, - {file = "coverage-7.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e"}, - {file = "coverage-7.3.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0"}, - {file = "coverage-7.3.0.tar.gz", hash = "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, ] [package.dependencies] @@ -543,40 +538,48 @@ toml = ["tomli"] [[package]] name = "cycler" -version = "0.11.0" +version = "0.12.1" description = "Composable style cycles" optional = true -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, ] +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "debugpy" -version = "1.6.7.post1" +version = "1.8.2" description = "An implementation of the Debug Adapter Protocol for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "debugpy-1.6.7.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:903bd61d5eb433b6c25b48eae5e23821d4c1a19e25c9610205f5aeaccae64e32"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16882030860081e7dd5aa619f30dec3c2f9a421e69861125f83cc372c94e57d"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win32.whl", hash = "sha256:eea8d8cfb9965ac41b99a61f8e755a8f50e9a20330938ad8271530210f54e09c"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win_amd64.whl", hash = "sha256:85969d864c45f70c3996067cfa76a319bae749b04171f2cdeceebe4add316155"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:890f7ab9a683886a0f185786ffbda3b46495c4b929dab083b8c79d6825832a52"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4ac7a4dba28801d184b7fc0e024da2635ca87d8b0a825c6087bb5168e3c0d28"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win32.whl", hash = "sha256:3370ef1b9951d15799ef7af41f8174194f3482ee689988379763ef61a5456426"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:65b28435a17cba4c09e739621173ff90c515f7b9e8ea469b92e3c28ef8e5cdfb"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:92b6dae8bfbd497c90596bbb69089acf7954164aea3228a99d7e43e5267f5b36"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72f5d2ecead8125cf669e62784ef1e6300f4067b0f14d9f95ee00ae06fc7c4f7"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win32.whl", hash = "sha256:f0851403030f3975d6e2eaa4abf73232ab90b98f041e3c09ba33be2beda43fcf"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win_amd64.whl", hash = "sha256:3de5d0f97c425dc49bce4293df6a04494309eedadd2b52c22e58d95107e178d9"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:38651c3639a4e8bbf0ca7e52d799f6abd07d622a193c406be375da4d510d968d"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038c51268367c9c935905a90b1c2d2dbfe304037c27ba9d19fe7409f8cdc710c"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win32.whl", hash = "sha256:4b9eba71c290852f959d2cf8a03af28afd3ca639ad374d393d53d367f7f685b2"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win_amd64.whl", hash = "sha256:973a97ed3b434eab0f792719a484566c35328196540676685c975651266fccf9"}, - {file = "debugpy-1.6.7.post1-py2.py3-none-any.whl", hash = "sha256:1093a5c541af079c13ac8c70ab8b24d1d35c8cacb676306cf11e57f699c02926"}, - {file = "debugpy-1.6.7.post1.zip", hash = "sha256:fe87ec0182ef624855d05e6ed7e0b7cb1359d2ffa2a925f8ec2d22e98b75d0ca"}, + {file = "debugpy-1.8.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7ee2e1afbf44b138c005e4380097d92532e1001580853a7cb40ed84e0ef1c3d2"}, + {file = "debugpy-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f8c3f7c53130a070f0fc845a0f2cee8ed88d220d6b04595897b66605df1edd6"}, + {file = "debugpy-1.8.2-cp310-cp310-win32.whl", hash = "sha256:f179af1e1bd4c88b0b9f0fa153569b24f6b6f3de33f94703336363ae62f4bf47"}, + {file = "debugpy-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:0600faef1d0b8d0e85c816b8bb0cb90ed94fc611f308d5fde28cb8b3d2ff0fe3"}, + {file = "debugpy-1.8.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8a13417ccd5978a642e91fb79b871baded925d4fadd4dfafec1928196292aa0a"}, + {file = "debugpy-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acdf39855f65c48ac9667b2801234fc64d46778021efac2de7e50907ab90c634"}, + {file = "debugpy-1.8.2-cp311-cp311-win32.whl", hash = "sha256:2cbd4d9a2fc5e7f583ff9bf11f3b7d78dfda8401e8bb6856ad1ed190be4281ad"}, + {file = "debugpy-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:d3408fddd76414034c02880e891ea434e9a9cf3a69842098ef92f6e809d09afa"}, + {file = "debugpy-1.8.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:5d3ccd39e4021f2eb86b8d748a96c766058b39443c1f18b2dc52c10ac2757835"}, + {file = "debugpy-1.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62658aefe289598680193ff655ff3940e2a601765259b123dc7f89c0239b8cd3"}, + {file = "debugpy-1.8.2-cp312-cp312-win32.whl", hash = "sha256:bd11fe35d6fd3431f1546d94121322c0ac572e1bfb1f6be0e9b8655fb4ea941e"}, + {file = "debugpy-1.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:15bc2f4b0f5e99bf86c162c91a74c0631dbd9cef3c6a1d1329c946586255e859"}, + {file = "debugpy-1.8.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:5a019d4574afedc6ead1daa22736c530712465c0c4cd44f820d803d937531b2d"}, + {file = "debugpy-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40f062d6877d2e45b112c0bbade9a17aac507445fd638922b1a5434df34aed02"}, + {file = "debugpy-1.8.2-cp38-cp38-win32.whl", hash = "sha256:c78ba1680f1015c0ca7115671fe347b28b446081dada3fedf54138f44e4ba031"}, + {file = "debugpy-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:cf327316ae0c0e7dd81eb92d24ba8b5e88bb4d1b585b5c0d32929274a66a5210"}, + {file = "debugpy-1.8.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1523bc551e28e15147815d1397afc150ac99dbd3a8e64641d53425dba57b0ff9"}, + {file = "debugpy-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e24ccb0cd6f8bfaec68d577cb49e9c680621c336f347479b3fce060ba7c09ec1"}, + {file = "debugpy-1.8.2-cp39-cp39-win32.whl", hash = "sha256:7f8d57a98c5a486c5c7824bc0b9f2f11189d08d73635c326abef268f83950326"}, + {file = "debugpy-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:16c8dcab02617b75697a0a925a62943e26a0330da076e2a10437edd9f0bf3755"}, + {file = "debugpy-1.8.2-py2.py3-none-any.whl", hash = "sha256:16e16df3a98a35c63c3ab1e4d19be4cbc7fdda92d9ddc059294f18910928e0ca"}, + {file = "debugpy-1.8.2.zip", hash = "sha256:95378ed08ed2089221896b9b3a8d021e642c24edc8fef20e5d4342ca8be65c00"}, ] [[package]] @@ -621,49 +624,50 @@ pygments = ["pygments (>=2.2.0)"] [[package]] name = "dill" -version = "0.3.7" +version = "0.3.8" description = "serialize all of Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, - {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, ] [package.extras] graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "distlib" -version = "0.3.7" +version = "0.3.8" description = "Distribution utilities" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, - {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] [[package]] name = "docutils" -version = "0.17.1" +version = "0.18.1" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, + {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, + {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] [[package]] name = "exceptiongroup" -version = "1.1.1" +version = "1.2.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, - {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] @@ -671,17 +675,17 @@ test = ["pytest (>=6)"] [[package]] name = "executing" -version = "1.2.0" +version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, ] [package.extras] -tests = ["asttokens", "littleutils", "pytest", "rich"] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] [[package]] name = "fancycompleter" @@ -700,13 +704,13 @@ pyrepl = ">=0.8.2" [[package]] name = "fastjsonschema" -version = "2.18.0" +version = "2.20.0" description = "Fastest Python implementation of JSON schema" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"}, - {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"}, + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, ] [package.extras] @@ -714,166 +718,165 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "filelock" -version = "3.12.2" +version = "3.15.4" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, + {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] +typing = ["typing-extensions (>=4.8)"] [[package]] name = "fonttools" -version = "4.43.0" +version = "4.53.1" description = "Tools to manipulate font files" optional = true python-versions = ">=3.8" files = [ - {file = "fonttools-4.43.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ab80e7d6bb01316d5fc8161a2660ca2e9e597d0880db4927bc866c76474472ef"}, - {file = "fonttools-4.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82d8e687a42799df5325e7ee12977b74738f34bf7fde1c296f8140efd699a213"}, - {file = "fonttools-4.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d08a694b280d615460563a6b4e2afb0b1b9df708c799ec212bf966652b94fc84"}, - {file = "fonttools-4.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d654d3e780e0ceabb1f4eff5a3c042c67d4428d0fe1ea3afd238a721cf171b3"}, - {file = "fonttools-4.43.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:20fc43783c432862071fa76da6fa714902ae587bc68441e12ff4099b94b1fcef"}, - {file = "fonttools-4.43.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33c40a657fb87ff83185828c0323032d63a4df1279d5c1c38e21f3ec56327803"}, - {file = "fonttools-4.43.0-cp310-cp310-win32.whl", hash = "sha256:b3813f57f85bbc0e4011a0e1e9211f9ee52f87f402e41dc05bc5135f03fa51c1"}, - {file = "fonttools-4.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:05056a8c9af048381fdb17e89b17d45f6c8394176d01e8c6fef5ac96ea950d38"}, - {file = "fonttools-4.43.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da78f39b601ed0b4262929403186d65cf7a016f91ff349ab18fdc5a7080af465"}, - {file = "fonttools-4.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5056f69a18f3f28ab5283202d1efcfe011585d31de09d8560f91c6c88f041e92"}, - {file = "fonttools-4.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcc01cea0a121fb0c009993497bad93cae25e77db7dee5345fec9cce1aaa09cd"}, - {file = "fonttools-4.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee728d5af70f117581712966a21e2e07031e92c687ef1fdc457ac8d281016f64"}, - {file = "fonttools-4.43.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b5e760198f0b87e42478bb35a6eae385c636208f6f0d413e100b9c9c5efafb6a"}, - {file = "fonttools-4.43.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:af38f5145258e9866da5881580507e6d17ff7756beef175d13213a43a84244e9"}, - {file = "fonttools-4.43.0-cp311-cp311-win32.whl", hash = "sha256:25620b738d4533cfc21fd2a4f4b667e481f7cb60e86b609799f7d98af657854e"}, - {file = "fonttools-4.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:635658464dccff6fa5c3b43fe8f818ae2c386ee6a9e1abc27359d1e255528186"}, - {file = "fonttools-4.43.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a682fb5cbf8837d1822b80acc0be5ff2ea0c49ca836e468a21ffd388ef280fd3"}, - {file = "fonttools-4.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3d7adfa342e6b3a2b36960981f23f480969f833d565a4eba259c2e6f59d2674f"}, - {file = "fonttools-4.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa67d1e720fdd902fde4a59d0880854ae9f19fc958f3e1538bceb36f7f4dc92"}, - {file = "fonttools-4.43.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77e5113233a2df07af9dbf493468ce526784c3b179c0e8b9c7838ced37c98b69"}, - {file = "fonttools-4.43.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:57c22e5f9f53630d458830f710424dce4f43c5f0d95cb3368c0f5178541e4db7"}, - {file = "fonttools-4.43.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:206808f9717c9b19117f461246372a2c160fa12b9b8dbdfb904ab50ca235ba0a"}, - {file = "fonttools-4.43.0-cp312-cp312-win32.whl", hash = "sha256:f19c2b1c65d57cbea25cabb80941fea3fbf2625ff0cdcae8900b5fb1c145704f"}, - {file = "fonttools-4.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7c76f32051159f8284f1a5f5b605152b5a530736fb8b55b09957db38dcae5348"}, - {file = "fonttools-4.43.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e3f8acc6ef4a627394021246e099faee4b343afd3ffe2e517d8195b4ebf20289"}, - {file = "fonttools-4.43.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a68b71adc3b3a90346e4ac92f0a69ab9caeba391f3b04ab6f1e98f2c8ebe88e3"}, - {file = "fonttools-4.43.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ace0fd5afb79849f599f76af5c6aa5e865bd042c811e4e047bbaa7752cc26126"}, - {file = "fonttools-4.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f9660e70a2430780e23830476332bc3391c3c8694769e2c0032a5038702a662"}, - {file = "fonttools-4.43.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:48078357984214ccd22d7fe0340cd6ff7286b2f74f173603a1a9a40b5dc25afe"}, - {file = "fonttools-4.43.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d27d960e10cf7617d70cf3104c32a69b008dde56f2d55a9bed4ba6e3df611544"}, - {file = "fonttools-4.43.0-cp38-cp38-win32.whl", hash = "sha256:a6a2e99bb9ea51e0974bbe71768df42c6dd189308c22f3f00560c3341b345646"}, - {file = "fonttools-4.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:030355fbb0cea59cf75d076d04d3852900583d1258574ff2d7d719abf4513836"}, - {file = "fonttools-4.43.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52e77f23a9c059f8be01a07300ba4c4d23dc271d33eed502aea5a01ab5d2f4c1"}, - {file = "fonttools-4.43.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a530fa28c155538d32214eafa0964989098a662bd63e91e790e6a7a4e9c02da"}, - {file = "fonttools-4.43.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70f021a6b9eb10dfe7a411b78e63a503a06955dd6d2a4e130906d8760474f77c"}, - {file = "fonttools-4.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:812142a0e53cc853964d487e6b40963df62f522b1b571e19d1ff8467d7880ceb"}, - {file = "fonttools-4.43.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ace51902ab67ef5fe225e8b361039e996db153e467e24a28d35f74849b37b7ce"}, - {file = "fonttools-4.43.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8dfd8edfce34ad135bd69de20c77449c06e2c92b38f2a8358d0987737f82b49e"}, - {file = "fonttools-4.43.0-cp39-cp39-win32.whl", hash = "sha256:e5d53eddaf436fa131042f44a76ea1ead0a17c354ab9de0d80e818f0cb1629f1"}, - {file = "fonttools-4.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:93c5b6d77baf28f306bc13fa987b0b13edca6a39dc2324eaca299a74ccc6316f"}, - {file = "fonttools-4.43.0-py3-none-any.whl", hash = "sha256:e4bc589d8da09267c7c4ceaaaa4fc01a7908ac5b43b286ac9279afe76407c384"}, - {file = "fonttools-4.43.0.tar.gz", hash = "sha256:b62a53a4ca83c32c6b78cac64464f88d02929779373c716f738af6968c8c821e"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "scipy"] -lxml = ["lxml (>=4.0,<5)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] repacker = ["uharfbuzz (>=0.23.0)"] symfont = ["sympy"] type1 = ["xattr"] ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.0.0)"] +unicode = ["unicodedata2 (>=15.1.0)"] woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] name = "greenlet" -version = "2.0.2" +version = "3.0.3" description = "Lightweight in-process concurrent programming" optional = true -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -files = [ - {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, - {file = "greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, - {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, - {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, - {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, - {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, - {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, - {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, - {file = "greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, - {file = "greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, - {file = "greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, - {file = "greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, - {file = "greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, - {file = "greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, - {file = "greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, - {file = "greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, - {file = "greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, - {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, - {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, - {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, - {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, - {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, - {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, - {file = "greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, - {file = "greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, - {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, -] - -[package.extras] -docs = ["Sphinx", "docutils (<0.18)"] +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] [[package]] name = "idna" -version = "3.4" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -889,40 +892,40 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.8.0" +version = "8.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "importlib-resources" -version = "6.0.1" +version = "6.4.0" description = "Read resources from Python packages" -optional = false +optional = true python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"}, - {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"}, + {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, + {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -937,13 +940,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.23.2" +version = "6.29.5" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.23.2-py3-none-any.whl", hash = "sha256:7ccb6e2d32fd958c21453db494c914f3474908a2fdefd99ab548a5375b548d1f"}, - {file = "ipykernel-6.23.2.tar.gz", hash = "sha256:fcfb67c5b504aa1bfcda1c5b3716636239e0f7b9290958f1c558c79b4c0e7ed5"}, + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, ] [package.dependencies] @@ -957,7 +960,7 @@ matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" psutil = "*" -pyzmq = ">=20" +pyzmq = ">=24" tornado = ">=6.1" traitlets = ">=5.4.0" @@ -966,73 +969,68 @@ cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] pyqt5 = ["pyqt5"] pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov", "pytest-timeout"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] [[package]] name = "ipython" -version = "8.12.2" +version = "8.18.1" description = "IPython: Productive Interactive Computing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"}, - {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"}, + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, ] [package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" -prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +prompt-toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "isort" -version = "5.12.0" +version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +colors = ["colorama (>=0.4.6)"] [[package]] name = "jedi" -version = "0.19.0" +version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" files = [ - {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, - {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, ] [package.dependencies] @@ -1041,17 +1039,17 @@ parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" -version = "3.1.3" +version = "3.1.4" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [package.dependencies] @@ -1062,51 +1060,48 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.19.0" +version = "4.23.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, - {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, ] [package.dependencies] attrs = ">=22.2.0" -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} jsonschema-specifications = ">=2023.03.6" -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} referencing = ">=0.28.4" rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] [[package]] name = "jsonschema-specifications" -version = "2023.7.1" +version = "2023.12.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, - {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, ] [package.dependencies] -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -referencing = ">=0.28.0" +referencing = ">=0.31.0" [[package]] name = "jupyter-client" -version = "8.3.0" +version = "8.6.2" description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.3.0-py3-none-any.whl", hash = "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158"}, - {file = "jupyter_client-8.3.0.tar.gz", hash = "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f"}, + {file = "jupyter_client-8.6.2-py3-none-any.whl", hash = "sha256:50cbc5c66fd1b8f65ecb66bc490ab73217993632809b6e505687de18e9dea39f"}, + {file = "jupyter_client-8.6.2.tar.gz", hash = "sha256:2bda14d55ee5ba58552a8c53ae43d215ad9868853489213f37da060ced54d8df"}, ] [package.dependencies] @@ -1119,17 +1114,17 @@ traitlets = ">=5.3" [package.extras] docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] [[package]] name = "jupyter-core" -version = "5.3.1" +version = "5.7.2" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.3.1-py3-none-any.whl", hash = "sha256:ae9036db959a71ec1cac33081eeb040a79e681f08ab68b0883e9a676c7a90dce"}, - {file = "jupyter_core-5.3.1.tar.gz", hash = "sha256:5ba5c7938a7f97a6b0481463f7ff0dbac7c15ba48cf46fa4035ca6e838aa1aba"}, + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, ] [package.dependencies] @@ -1138,231 +1133,217 @@ pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_ traitlets = ">=5.3" [package.extras] -docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] [[package]] name = "jupyterlab-pygments" -version = "0.2.2" +version = "0.3.0" description = "Pygments theme using JupyterLab CSS variables" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, - {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, + {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, + {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, ] [[package]] name = "kiwisolver" -version = "1.4.4" +version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" optional = true python-versions = ">=3.7" files = [ - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, - {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, ] [[package]] name = "latexcodec" -version = "2.0.1" +version = "3.0.0" description = "A lexer and codec to work with LaTeX code in Python." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, - {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, -] - -[package.dependencies] -six = ">=1.4.1" - -[[package]] -name = "lazy-object-proxy" -version = "1.9.0" -description = "A fast and thorough lazy object proxy." -optional = false python-versions = ">=3.7" files = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, + {file = "latexcodec-3.0.0-py3-none-any.whl", hash = "sha256:6f3477ad5e61a0a99bd31a6a370c34e88733a6bad9c921a3ffcfacada12f41a7"}, + {file = "latexcodec-3.0.0.tar.gz", hash = "sha256:917dc5fe242762cc19d963e6548b42d63a118028cdd3361d62397e3b638b6bc5"}, ] [[package]] name = "llvmlite" -version = "0.40.1" +version = "0.42.0" description = "lightweight wrapper around basic LLVM functionality" optional = false -python-versions = ">=3.8" -files = [ - {file = "llvmlite-0.40.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:84ce9b1c7a59936382ffde7871978cddcda14098e5a76d961e204523e5c372fb"}, - {file = "llvmlite-0.40.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3673c53cb21c65d2ff3704962b5958e967c6fc0bd0cff772998face199e8d87b"}, - {file = "llvmlite-0.40.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bba2747cf5b4954e945c287fe310b3fcc484e2a9d1b0c273e99eb17d103bb0e6"}, - {file = "llvmlite-0.40.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbd5e82cc990e5a3e343a3bf855c26fdfe3bfae55225f00efd01c05bbda79918"}, - {file = "llvmlite-0.40.1-cp310-cp310-win32.whl", hash = "sha256:09f83ea7a54509c285f905d968184bba00fc31ebf12f2b6b1494d677bb7dde9b"}, - {file = "llvmlite-0.40.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b37297f3cbd68d14a97223a30620589d98ad1890e5040c9e5fc181063f4ed49"}, - {file = "llvmlite-0.40.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a66a5bd580951751b4268f4c3bddcef92682814d6bc72f3cd3bb67f335dd7097"}, - {file = "llvmlite-0.40.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:467b43836b388eaedc5a106d76761e388dbc4674b2f2237bc477c6895b15a634"}, - {file = "llvmlite-0.40.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c23edd196bd797dc3a7860799054ea3488d2824ecabc03f9135110c2e39fcbc"}, - {file = "llvmlite-0.40.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a36d9f244b6680cb90bbca66b146dabb2972f4180c64415c96f7c8a2d8b60a36"}, - {file = "llvmlite-0.40.1-cp311-cp311-win_amd64.whl", hash = "sha256:5b3076dc4e9c107d16dc15ecb7f2faf94f7736cd2d5e9f4dc06287fd672452c1"}, - {file = "llvmlite-0.40.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a7525db121f2e699809b539b5308228854ccab6693ecb01b52c44a2f5647e20"}, - {file = "llvmlite-0.40.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:84747289775d0874e506f907a4513db889471607db19b04de97d144047fec885"}, - {file = "llvmlite-0.40.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e35766e42acef0fe7d1c43169a8ffc327a47808fae6a067b049fe0e9bbf84dd5"}, - {file = "llvmlite-0.40.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cda71de10a1f48416309e408ea83dab5bf36058f83e13b86a2961defed265568"}, - {file = "llvmlite-0.40.1-cp38-cp38-win32.whl", hash = "sha256:96707ebad8b051bbb4fc40c65ef93b7eeee16643bd4d579a14d11578e4b7a647"}, - {file = "llvmlite-0.40.1-cp38-cp38-win_amd64.whl", hash = "sha256:e44f854dc11559795bcdeaf12303759e56213d42dabbf91a5897aa2d8b033810"}, - {file = "llvmlite-0.40.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f643d15aacd0b0b0dc8b74b693822ba3f9a53fa63bc6a178c2dba7cc88f42144"}, - {file = "llvmlite-0.40.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39a0b4d0088c01a469a5860d2e2d7a9b4e6a93c0f07eb26e71a9a872a8cadf8d"}, - {file = "llvmlite-0.40.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9329b930d699699846623054121ed105fd0823ed2180906d3b3235d361645490"}, - {file = "llvmlite-0.40.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2dbbb8424037ca287983b115a29adf37d806baf7e1bf4a67bd2cffb74e085ed"}, - {file = "llvmlite-0.40.1-cp39-cp39-win32.whl", hash = "sha256:e74e7bec3235a1e1c9ad97d897a620c5007d0ed80c32c84c1d787e7daa17e4ec"}, - {file = "llvmlite-0.40.1-cp39-cp39-win_amd64.whl", hash = "sha256:ff8f31111bb99d135ff296757dc81ab36c2dee54ed4bd429158a96da9807c316"}, - {file = "llvmlite-0.40.1.tar.gz", hash = "sha256:5cdb0d45df602099d833d50bd9e81353a5e036242d3c003c5b294fc61d1986b4"}, +python-versions = ">=3.9" +files = [ + {file = "llvmlite-0.42.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3366938e1bf63d26c34fbfb4c8e8d2ded57d11e0567d5bb243d89aab1eb56098"}, + {file = "llvmlite-0.42.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c35da49666a21185d21b551fc3caf46a935d54d66969d32d72af109b5e7d2b6f"}, + {file = "llvmlite-0.42.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70f44ccc3c6220bd23e0ba698a63ec2a7d3205da0d848804807f37fc243e3f77"}, + {file = "llvmlite-0.42.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763f8d8717a9073b9e0246998de89929071d15b47f254c10eef2310b9aac033d"}, + {file = "llvmlite-0.42.0-cp310-cp310-win_amd64.whl", hash = "sha256:8d90edf400b4ceb3a0e776b6c6e4656d05c7187c439587e06f86afceb66d2be5"}, + {file = "llvmlite-0.42.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ae511caed28beaf1252dbaf5f40e663f533b79ceb408c874c01754cafabb9cbf"}, + {file = "llvmlite-0.42.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81e674c2fe85576e6c4474e8c7e7aba7901ac0196e864fe7985492b737dbab65"}, + {file = "llvmlite-0.42.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb3975787f13eb97629052edb5017f6c170eebc1c14a0433e8089e5db43bcce6"}, + {file = "llvmlite-0.42.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5bece0cdf77f22379f19b1959ccd7aee518afa4afbd3656c6365865f84903f9"}, + {file = "llvmlite-0.42.0-cp311-cp311-win_amd64.whl", hash = "sha256:7e0c4c11c8c2aa9b0701f91b799cb9134a6a6de51444eff5a9087fc7c1384275"}, + {file = "llvmlite-0.42.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:08fa9ab02b0d0179c688a4216b8939138266519aaa0aa94f1195a8542faedb56"}, + {file = "llvmlite-0.42.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b2fce7d355068494d1e42202c7aff25d50c462584233013eb4470c33b995e3ee"}, + {file = "llvmlite-0.42.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebe66a86dc44634b59a3bc860c7b20d26d9aaffcd30364ebe8ba79161a9121f4"}, + {file = "llvmlite-0.42.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d47494552559e00d81bfb836cf1c4d5a5062e54102cc5767d5aa1e77ccd2505c"}, + {file = "llvmlite-0.42.0-cp312-cp312-win_amd64.whl", hash = "sha256:05cb7e9b6ce69165ce4d1b994fbdedca0c62492e537b0cc86141b6e2c78d5888"}, + {file = "llvmlite-0.42.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bdd3888544538a94d7ec99e7c62a0cdd8833609c85f0c23fcb6c5c591aec60ad"}, + {file = "llvmlite-0.42.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d0936c2067a67fb8816c908d5457d63eba3e2b17e515c5fe00e5ee2bace06040"}, + {file = "llvmlite-0.42.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a78ab89f1924fc11482209f6799a7a3fc74ddc80425a7a3e0e8174af0e9e2301"}, + {file = "llvmlite-0.42.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7599b65c7af7abbc978dbf345712c60fd596aa5670496561cc10e8a71cebfb2"}, + {file = "llvmlite-0.42.0-cp39-cp39-win_amd64.whl", hash = "sha256:43d65cc4e206c2e902c1004dd5418417c4efa6c1d04df05c6c5675a27e8ca90e"}, + {file = "llvmlite-0.42.0.tar.gz", hash = "sha256:f92b09243c0cc3f457da8b983f67bd8e1295d0f5b3746c7a1861d7a99403854a"}, ] [[package]] name = "lz4" -version = "4.3.2" +version = "4.3.3" description = "LZ4 Bindings for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "lz4-4.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1c4c100d99eed7c08d4e8852dd11e7d1ec47a3340f49e3a96f8dfbba17ffb300"}, - {file = "lz4-4.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:edd8987d8415b5dad25e797043936d91535017237f72fa456601be1479386c92"}, - {file = "lz4-4.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7c50542b4ddceb74ab4f8b3435327a0861f06257ca501d59067a6a482535a77"}, - {file = "lz4-4.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f5614d8229b33d4a97cb527db2a1ac81308c6e796e7bdb5d1309127289f69d5"}, - {file = "lz4-4.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f00a9ba98f6364cadda366ae6469b7b3568c0cced27e16a47ddf6b774169270"}, - {file = "lz4-4.3.2-cp310-cp310-win32.whl", hash = "sha256:b10b77dc2e6b1daa2f11e241141ab8285c42b4ed13a8642495620416279cc5b2"}, - {file = "lz4-4.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:86480f14a188c37cb1416cdabacfb4e42f7a5eab20a737dac9c4b1c227f3b822"}, - {file = "lz4-4.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7c2df117def1589fba1327dceee51c5c2176a2b5a7040b45e84185ce0c08b6a3"}, - {file = "lz4-4.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1f25eb322eeb24068bb7647cae2b0732b71e5c639e4e4026db57618dcd8279f0"}, - {file = "lz4-4.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8df16c9a2377bdc01e01e6de5a6e4bbc66ddf007a6b045688e285d7d9d61d1c9"}, - {file = "lz4-4.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f571eab7fec554d3b1db0d666bdc2ad85c81f4b8cb08906c4c59a8cad75e6e22"}, - {file = "lz4-4.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7211dc8f636ca625abc3d4fb9ab74e5444b92df4f8d58ec83c8868a2b0ff643d"}, - {file = "lz4-4.3.2-cp311-cp311-win32.whl", hash = "sha256:867664d9ca9bdfce840ac96d46cd8838c9ae891e859eb98ce82fcdf0e103a947"}, - {file = "lz4-4.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:a6a46889325fd60b8a6b62ffc61588ec500a1883db32cddee9903edfba0b7584"}, - {file = "lz4-4.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a85b430138882f82f354135b98c320dafb96fc8fe4656573d95ab05de9eb092"}, - {file = "lz4-4.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65d5c93f8badacfa0456b660285e394e65023ef8071142e0dcbd4762166e1be0"}, - {file = "lz4-4.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b50f096a6a25f3b2edca05aa626ce39979d63c3b160687c8c6d50ac3943d0ba"}, - {file = "lz4-4.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:200d05777d61ba1ff8d29cb51c534a162ea0b4fe6d3c28be3571a0a48ff36080"}, - {file = "lz4-4.3.2-cp37-cp37m-win32.whl", hash = "sha256:edc2fb3463d5d9338ccf13eb512aab61937be50aa70734bcf873f2f493801d3b"}, - {file = "lz4-4.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:83acfacab3a1a7ab9694333bcb7950fbeb0be21660d236fd09c8337a50817897"}, - {file = "lz4-4.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7a9eec24ec7d8c99aab54de91b4a5a149559ed5b3097cf30249b665689b3d402"}, - {file = "lz4-4.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:31d72731c4ac6ebdce57cd9a5cabe0aecba229c4f31ba3e2c64ae52eee3fdb1c"}, - {file = "lz4-4.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83903fe6db92db0be101acedc677aa41a490b561567fe1b3fe68695b2110326c"}, - {file = "lz4-4.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926b26db87ec8822cf1870efc3d04d06062730ec3279bbbd33ba47a6c0a5c673"}, - {file = "lz4-4.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e05afefc4529e97c08e65ef92432e5f5225c0bb21ad89dee1e06a882f91d7f5e"}, - {file = "lz4-4.3.2-cp38-cp38-win32.whl", hash = "sha256:ad38dc6a7eea6f6b8b642aaa0683253288b0460b70cab3216838747163fb774d"}, - {file = "lz4-4.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:7e2dc1bd88b60fa09b9b37f08553f45dc2b770c52a5996ea52b2b40f25445676"}, - {file = "lz4-4.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:edda4fb109439b7f3f58ed6bede59694bc631c4b69c041112b1b7dc727fffb23"}, - {file = "lz4-4.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ca83a623c449295bafad745dcd399cea4c55b16b13ed8cfea30963b004016c9"}, - {file = "lz4-4.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5ea0e788dc7e2311989b78cae7accf75a580827b4d96bbaf06c7e5a03989bd5"}, - {file = "lz4-4.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a98b61e504fb69f99117b188e60b71e3c94469295571492a6468c1acd63c37ba"}, - {file = "lz4-4.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4931ab28a0d1c133104613e74eec1b8bb1f52403faabe4f47f93008785c0b929"}, - {file = "lz4-4.3.2-cp39-cp39-win32.whl", hash = "sha256:ec6755cacf83f0c5588d28abb40a1ac1643f2ff2115481089264c7630236618a"}, - {file = "lz4-4.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:4caedeb19e3ede6c7a178968b800f910db6503cb4cb1e9cc9221157572139b49"}, - {file = "lz4-4.3.2.tar.gz", hash = "sha256:e1431d84a9cfb23e6773e72078ce8e65cad6745816d4cbf9ae67da5ea419acda"}, + {file = "lz4-4.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b891880c187e96339474af2a3b2bfb11a8e4732ff5034be919aa9029484cd201"}, + {file = "lz4-4.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:222a7e35137d7539c9c33bb53fcbb26510c5748779364014235afc62b0ec797f"}, + {file = "lz4-4.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f76176492ff082657ada0d0f10c794b6da5800249ef1692b35cf49b1e93e8ef7"}, + {file = "lz4-4.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1d18718f9d78182c6b60f568c9a9cec8a7204d7cb6fad4e511a2ef279e4cb05"}, + {file = "lz4-4.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cdc60e21ec70266947a48839b437d46025076eb4b12c76bd47f8e5eb8a75dcc"}, + {file = "lz4-4.3.3-cp310-cp310-win32.whl", hash = "sha256:c81703b12475da73a5d66618856d04b1307e43428a7e59d98cfe5a5d608a74c6"}, + {file = "lz4-4.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:43cf03059c0f941b772c8aeb42a0813d68d7081c009542301637e5782f8a33e2"}, + {file = "lz4-4.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30e8c20b8857adef7be045c65f47ab1e2c4fabba86a9fa9a997d7674a31ea6b6"}, + {file = "lz4-4.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2f7b1839f795315e480fb87d9bc60b186a98e3e5d17203c6e757611ef7dcef61"}, + {file = "lz4-4.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edfd858985c23523f4e5a7526ca6ee65ff930207a7ec8a8f57a01eae506aaee7"}, + {file = "lz4-4.3.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e9c410b11a31dbdc94c05ac3c480cb4b222460faf9231f12538d0074e56c563"}, + {file = "lz4-4.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2507ee9c99dbddd191c86f0e0c8b724c76d26b0602db9ea23232304382e1f21"}, + {file = "lz4-4.3.3-cp311-cp311-win32.whl", hash = "sha256:f180904f33bdd1e92967923a43c22899e303906d19b2cf8bb547db6653ea6e7d"}, + {file = "lz4-4.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:b14d948e6dce389f9a7afc666d60dd1e35fa2138a8ec5306d30cd2e30d36b40c"}, + {file = "lz4-4.3.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e36cd7b9d4d920d3bfc2369840da506fa68258f7bb176b8743189793c055e43d"}, + {file = "lz4-4.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:31ea4be9d0059c00b2572d700bf2c1bc82f241f2c3282034a759c9a4d6ca4dc2"}, + {file = "lz4-4.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33c9a6fd20767ccaf70649982f8f3eeb0884035c150c0b818ea660152cf3c809"}, + {file = "lz4-4.3.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca8fccc15e3add173da91be8f34121578dc777711ffd98d399be35487c934bf"}, + {file = "lz4-4.3.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d84b479ddf39fe3ea05387f10b779155fc0990125f4fb35d636114e1c63a2e"}, + {file = "lz4-4.3.3-cp312-cp312-win32.whl", hash = "sha256:337cb94488a1b060ef1685187d6ad4ba8bc61d26d631d7ba909ee984ea736be1"}, + {file = "lz4-4.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:5d35533bf2cee56f38ced91f766cd0038b6abf46f438a80d50c52750088be93f"}, + {file = "lz4-4.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:363ab65bf31338eb364062a15f302fc0fab0a49426051429866d71c793c23394"}, + {file = "lz4-4.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a136e44a16fc98b1abc404fbabf7f1fada2bdab6a7e970974fb81cf55b636d0"}, + {file = "lz4-4.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abc197e4aca8b63f5ae200af03eb95fb4b5055a8f990079b5bdf042f568469dd"}, + {file = "lz4-4.3.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56f4fe9c6327adb97406f27a66420b22ce02d71a5c365c48d6b656b4aaeb7775"}, + {file = "lz4-4.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0e822cd7644995d9ba248cb4b67859701748a93e2ab7fc9bc18c599a52e4604"}, + {file = "lz4-4.3.3-cp38-cp38-win32.whl", hash = "sha256:24b3206de56b7a537eda3a8123c644a2b7bf111f0af53bc14bed90ce5562d1aa"}, + {file = "lz4-4.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:b47839b53956e2737229d70714f1d75f33e8ac26e52c267f0197b3189ca6de24"}, + {file = "lz4-4.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6756212507405f270b66b3ff7f564618de0606395c0fe10a7ae2ffcbbe0b1fba"}, + {file = "lz4-4.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee9ff50557a942d187ec85462bb0960207e7ec5b19b3b48949263993771c6205"}, + {file = "lz4-4.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b901c7784caac9a1ded4555258207d9e9697e746cc8532129f150ffe1f6ba0d"}, + {file = "lz4-4.3.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d9ec061b9eca86e4dcc003d93334b95d53909afd5a32c6e4f222157b50c071"}, + {file = "lz4-4.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4c7bf687303ca47d69f9f0133274958fd672efaa33fb5bcde467862d6c621f0"}, + {file = "lz4-4.3.3-cp39-cp39-win32.whl", hash = "sha256:054b4631a355606e99a42396f5db4d22046a3397ffc3269a348ec41eaebd69d2"}, + {file = "lz4-4.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:eac9af361e0d98335a02ff12fb56caeb7ea1196cf1a49dbf6f17828a131da807"}, + {file = "lz4-4.3.3.tar.gz", hash = "sha256:01fe674ef2889dbb9899d8a67361e0c4a2c833af5aeb37dd505727cf5d2a131e"}, ] [package.extras] @@ -1372,111 +1353,109 @@ tests = ["psutil", "pytest (!=3.3.0)", "pytest-cov"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] name = "matplotlib" -version = "3.7.2" +version = "3.9.1" description = "Python plotting package" optional = true -python-versions = ">=3.8" -files = [ - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"}, - {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"}, - {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"}, - {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"}, - {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"}, - {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"}, - {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"}, - {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"}, - {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"}, - {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"}, +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ccd6270066feb9a9d8e0705aa027f1ff39f354c72a87efe8fa07632f30fc6bb"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:591d3a88903a30a6d23b040c1e44d1afdd0d778758d07110eb7596f811f31842"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0"}, + {file = "matplotlib-3.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5"}, + {file = "matplotlib-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f"}, + {file = "matplotlib-3.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3"}, + {file = "matplotlib-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b"}, + {file = "matplotlib-3.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c"}, + {file = "matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049"}, + {file = "matplotlib-3.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff"}, + {file = "matplotlib-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"}, + {file = "matplotlib-3.9.1.tar.gz", hash = "sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010"}, ] [package.dependencies] @@ -1484,22 +1463,25 @@ contourpy = ">=1.0.1" cycler = ">=0.10" fonttools = ">=4.22.0" importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} -kiwisolver = ">=1.0.1" -numpy = ">=1.20" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" packaging = ">=20.0" -pillow = ">=6.2.0" -pyparsing = ">=2.3.1,<3.1" +pillow = ">=8" +pyparsing = ">=2.3.1" python-dateutil = ">=2.7" +[package.extras] +dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] + [[package]] name = "matplotlib-inline" -version = "0.1.6" +version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, - {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, ] [package.dependencies] @@ -1518,24 +1500,24 @@ files = [ [[package]] name = "mistune" -version = "3.0.1" +version = "3.0.2" description = "A sane and fast Markdown parser with useful plugins and renderers" optional = false python-versions = ">=3.7" files = [ - {file = "mistune-3.0.1-py3-none-any.whl", hash = "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6"}, - {file = "mistune-3.0.1.tar.gz", hash = "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c"}, + {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, + {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, ] [[package]] name = "nbclient" -version = "0.8.0" +version = "0.10.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." optional = false python-versions = ">=3.8.0" files = [ - {file = "nbclient-0.8.0-py3-none-any.whl", hash = "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548"}, - {file = "nbclient-0.8.0.tar.gz", hash = "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55"}, + {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, + {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, ] [package.dependencies] @@ -1547,17 +1529,17 @@ traitlets = ">=5.4" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" -version = "7.5.0" -description = "Converting Jupyter Notebooks" +version = "7.16.4" +description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." optional = false python-versions = ">=3.8" files = [ - {file = "nbconvert-7.5.0-py3-none-any.whl", hash = "sha256:852e44392d5650ef217a5ce3a8050747051d4e6ba75f0574cb5435049ee6c0d9"}, - {file = "nbconvert-7.5.0.tar.gz", hash = "sha256:f78fd22fd2410b960d5d9bcecf3e1d6c7bdc5fec2c865964c84aa4e74e6e88da"}, + {file = "nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3"}, + {file = "nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4"}, ] [package.dependencies] @@ -1579,29 +1561,29 @@ tinycss2 = "*" traitlets = ">=5.1" [package.extras] -all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] +all = ["flaky", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (==5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["nbconvert[qtpng]"] +qtpdf = ["pyqtwebengine (>=5.15)"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] webpdf = ["playwright"] [[package]] name = "nbformat" -version = "5.9.2" +version = "5.10.4" description = "The Jupyter Notebook format" optional = false python-versions = ">=3.8" files = [ - {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, - {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, + {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}, + {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}, ] [package.dependencies] -fastjsonschema = "*" +fastjsonschema = ">=2.15" jsonschema = ">=2.6" -jupyter-core = "*" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" traitlets = ">=5.1" [package.extras] @@ -1629,174 +1611,203 @@ traitlets = ">=5" [[package]] name = "nest-asyncio" -version = "1.5.7" +version = "1.6.0" description = "Patch asyncio to allow nested event loops" optional = false python-versions = ">=3.5" files = [ - {file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"}, - {file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"}, + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, ] [[package]] name = "numba" -version = "0.57.1" +version = "0.59.1" description = "compiling Python code using LLVM" optional = false -python-versions = ">=3.8" -files = [ - {file = "numba-0.57.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db8268eb5093cae2288942a8cbd69c9352f6fe6e0bfa0a9a27679436f92e4248"}, - {file = "numba-0.57.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:643cb09a9ba9e1bd8b060e910aeca455e9442361e80fce97690795ff9840e681"}, - {file = "numba-0.57.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:53e9fab973d9e82c9f8449f75994a898daaaf821d84f06fbb0b9de2293dd9306"}, - {file = "numba-0.57.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c0602e4f896e6a6d844517c3ab434bc978e7698a22a733cc8124465898c28fa8"}, - {file = "numba-0.57.1-cp310-cp310-win32.whl", hash = "sha256:3d6483c27520d16cf5d122868b79cad79e48056ecb721b52d70c126bed65431e"}, - {file = "numba-0.57.1-cp310-cp310-win_amd64.whl", hash = "sha256:a32ee263649aa3c3587b833d6311305379529570e6c20deb0c6f4fb5bc7020db"}, - {file = "numba-0.57.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c078f84b5529a7fdb8413bb33d5100f11ec7b44aa705857d9eb4e54a54ff505"}, - {file = "numba-0.57.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e447c4634d1cc99ab50d4faa68f680f1d88b06a2a05acf134aa6fcc0342adeca"}, - {file = "numba-0.57.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4838edef2df5f056cb8974670f3d66562e751040c448eb0b67c7e2fec1726649"}, - {file = "numba-0.57.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9b17fbe4a69dcd9a7cd49916b6463cd9a82af5f84911feeb40793b8bce00dfa7"}, - {file = "numba-0.57.1-cp311-cp311-win_amd64.whl", hash = "sha256:93df62304ada9b351818ba19b1cfbddaf72cd89348e81474326ca0b23bf0bae1"}, - {file = "numba-0.57.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8e00ca63c5d0ad2beeb78d77f087b3a88c45ea9b97e7622ab2ec411a868420ee"}, - {file = "numba-0.57.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ff66d5b022af6c7d81ddbefa87768e78ed4f834ab2da6ca2fd0d60a9e69b94f5"}, - {file = "numba-0.57.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:60ec56386076e9eed106a87c96626d5686fbb16293b9834f0849cf78c9491779"}, - {file = "numba-0.57.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c057ccedca95df23802b6ccad86bb318be624af45b5a38bb8412882be57a681"}, - {file = "numba-0.57.1-cp38-cp38-win32.whl", hash = "sha256:5a82bf37444039c732485c072fda21a361790ed990f88db57fd6941cd5e5d307"}, - {file = "numba-0.57.1-cp38-cp38-win_amd64.whl", hash = "sha256:9bcc36478773ce838f38afd9a4dfafc328d4ffb1915381353d657da7f6473282"}, - {file = "numba-0.57.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae50c8c90c2ce8057f9618b589223e13faa8cbc037d8f15b4aad95a2c33a0582"}, - {file = "numba-0.57.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9a1b2b69448e510d672ff9a6b18d2db9355241d93c6a77677baa14bec67dc2a0"}, - {file = "numba-0.57.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3cf78d74ad9d289fbc1e5b1c9f2680fca7a788311eb620581893ab347ec37a7e"}, - {file = "numba-0.57.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f47dd214adc5dcd040fe9ad2adbd2192133c9075d2189ce1b3d5f9d72863ef05"}, - {file = "numba-0.57.1-cp39-cp39-win32.whl", hash = "sha256:a3eac19529956185677acb7f01864919761bfffbb9ae04bbbe5e84bbc06cfc2b"}, - {file = "numba-0.57.1-cp39-cp39-win_amd64.whl", hash = "sha256:9587ba1bf5f3035575e45562ada17737535c6d612df751e811d702693a72d95e"}, - {file = "numba-0.57.1.tar.gz", hash = "sha256:33c0500170d213e66d90558ad6aca57d3e03e97bb11da82e6d87ab793648cb17"}, +python-versions = ">=3.9" +files = [ + {file = "numba-0.59.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97385a7f12212c4f4bc28f648720a92514bee79d7063e40ef66c2d30600fd18e"}, + {file = "numba-0.59.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0b77aecf52040de2a1eb1d7e314497b9e56fba17466c80b457b971a25bb1576d"}, + {file = "numba-0.59.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3476a4f641bfd58f35ead42f4dcaf5f132569c4647c6f1360ccf18ee4cda3990"}, + {file = "numba-0.59.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:525ef3f820931bdae95ee5379c670d5c97289c6520726bc6937a4a7d4230ba24"}, + {file = "numba-0.59.1-cp310-cp310-win_amd64.whl", hash = "sha256:990e395e44d192a12105eca3083b61307db7da10e093972ca285c85bef0963d6"}, + {file = "numba-0.59.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43727e7ad20b3ec23ee4fc642f5b61845c71f75dd2825b3c234390c6d8d64051"}, + {file = "numba-0.59.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:411df625372c77959570050e861981e9d196cc1da9aa62c3d6a836b5cc338966"}, + {file = "numba-0.59.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2801003caa263d1e8497fb84829a7ecfb61738a95f62bc05693fcf1733e978e4"}, + {file = "numba-0.59.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dd2842fac03be4e5324ebbbd4d2d0c8c0fc6e0df75c09477dd45b288a0777389"}, + {file = "numba-0.59.1-cp311-cp311-win_amd64.whl", hash = "sha256:0594b3dfb369fada1f8bb2e3045cd6c61a564c62e50cf1f86b4666bc721b3450"}, + {file = "numba-0.59.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1cce206a3b92836cdf26ef39d3a3242fec25e07f020cc4feec4c4a865e340569"}, + {file = "numba-0.59.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8c8b4477763cb1fbd86a3be7050500229417bf60867c93e131fd2626edb02238"}, + {file = "numba-0.59.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d80bce4ef7e65bf895c29e3889ca75a29ee01da80266a01d34815918e365835"}, + {file = "numba-0.59.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f7ad1d217773e89a9845886401eaaab0a156a90aa2f179fdc125261fd1105096"}, + {file = "numba-0.59.1-cp312-cp312-win_amd64.whl", hash = "sha256:5bf68f4d69dd3a9f26a9b23548fa23e3bcb9042e2935257b471d2a8d3c424b7f"}, + {file = "numba-0.59.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e0318ae729de6e5dbe64c75ead1a95eb01fabfe0e2ebed81ebf0344d32db0ae"}, + {file = "numba-0.59.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0f68589740a8c38bb7dc1b938b55d1145244c8353078eea23895d4f82c8b9ec1"}, + {file = "numba-0.59.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:649913a3758891c77c32e2d2a3bcbedf4a69f5fea276d11f9119677c45a422e8"}, + {file = "numba-0.59.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9712808e4545270291d76b9a264839ac878c5eb7d8b6e02c970dc0ac29bc8187"}, + {file = "numba-0.59.1-cp39-cp39-win_amd64.whl", hash = "sha256:8d51ccd7008a83105ad6a0082b6a2b70f1142dc7cfd76deb8c5a862367eb8c86"}, + {file = "numba-0.59.1.tar.gz", hash = "sha256:76f69132b96028d2774ed20415e8c528a34e3299a40581bae178f0994a2f370b"}, ] [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.9\""} -llvmlite = "==0.40.*" -numpy = ">=1.21,<1.25" +llvmlite = "==0.42.*" +numpy = ">=1.22,<1.27" [[package]] name = "numpy" -version = "1.24.4" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.8" -files = [ - {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, - {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, - {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, - {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, - {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, - {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, - {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, - {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, - {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, - {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, - {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] name = "packaging" -version = "23.1" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] name = "pandas" -version = "1.5.3" +version = "2.2.2" description = "Powerful data structures for data analysis, time series, and statistics" optional = true -python-versions = ">=3.8" -files = [ - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, - {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, - {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, - {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, - {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, - {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, - {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, - {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, ] [package.dependencies] numpy = [ - {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] -python-dateutil = ">=2.8.1" +python-dateutil = ">=2.8.2" pytz = ">=2020.1" +tzdata = ">=2022.7" [package.extras] -test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] [[package]] name = "pandocfilters" -version = "1.5.0" +version = "1.5.1" description = "Utilities for writing pandoc filters in python" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, - {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, ] [[package]] name = "parso" -version = "0.8.3" +version = "0.8.4" description = "A Python Parser" optional = false python-versions = ">=3.6" files = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, ] [package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] [[package]] name = "pdbpp" @@ -1820,165 +1831,239 @@ testing = ["funcsigs", "pytest"] [[package]] name = "pendulum" -version = "2.1.2" +version = "3.0.0" description = "Python datetimes made easy" optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.8" files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, + {file = "pendulum-3.0.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2cf9e53ef11668e07f73190c805dbdf07a1939c3298b78d5a9203a86775d1bfd"}, + {file = "pendulum-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fb551b9b5e6059377889d2d878d940fd0bbb80ae4810543db18e6f77b02c5ef6"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c58227ac260d5b01fc1025176d7b31858c9f62595737f350d22124a9a3ad82d"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60fb6f415fea93a11c52578eaa10594568a6716602be8430b167eb0d730f3332"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b69f6b4dbcb86f2c2fe696ba991e67347bcf87fe601362a1aba6431454b46bde"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:138afa9c373ee450ede206db5a5e9004fd3011b3c6bbe1e57015395cd076a09f"}, + {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:83d9031f39c6da9677164241fd0d37fbfc9dc8ade7043b5d6d62f56e81af8ad2"}, + {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0c2308af4033fa534f089595bcd40a95a39988ce4059ccd3dc6acb9ef14ca44a"}, + {file = "pendulum-3.0.0-cp310-none-win_amd64.whl", hash = "sha256:9a59637cdb8462bdf2dbcb9d389518c0263799189d773ad5c11db6b13064fa79"}, + {file = "pendulum-3.0.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3725245c0352c95d6ca297193192020d1b0c0f83d5ee6bb09964edc2b5a2d508"}, + {file = "pendulum-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c035f03a3e565ed132927e2c1b691de0dbf4eb53b02a5a3c5a97e1a64e17bec"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597e66e63cbd68dd6d58ac46cb7a92363d2088d37ccde2dae4332ef23e95cd00"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99a0f8172e19f3f0c0e4ace0ad1595134d5243cf75985dc2233e8f9e8de263ca"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:77d8839e20f54706aed425bec82a83b4aec74db07f26acd039905d1237a5e1d4"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afde30e8146292b059020fbc8b6f8fd4a60ae7c5e6f0afef937bbb24880bdf01"}, + {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:660434a6fcf6303c4efd36713ca9212c753140107ee169a3fc6c49c4711c2a05"}, + {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dee9e5a48c6999dc1106eb7eea3e3a50e98a50651b72c08a87ee2154e544b33e"}, + {file = "pendulum-3.0.0-cp311-none-win_amd64.whl", hash = "sha256:d4cdecde90aec2d67cebe4042fd2a87a4441cc02152ed7ed8fb3ebb110b94ec4"}, + {file = "pendulum-3.0.0-cp311-none-win_arm64.whl", hash = "sha256:773c3bc4ddda2dda9f1b9d51fe06762f9200f3293d75c4660c19b2614b991d83"}, + {file = "pendulum-3.0.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:409e64e41418c49f973d43a28afe5df1df4f1dd87c41c7c90f1a63f61ae0f1f7"}, + {file = "pendulum-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a38ad2121c5ec7c4c190c7334e789c3b4624798859156b138fcc4d92295835dc"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fde4d0b2024b9785f66b7f30ed59281bd60d63d9213cda0eb0910ead777f6d37"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b2c5675769fb6d4c11238132962939b960fcb365436b6d623c5864287faa319"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8af95e03e066826f0f4c65811cbee1b3123d4a45a1c3a2b4fc23c4b0dff893b5"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2165a8f33cb15e06c67070b8afc87a62b85c5a273e3aaa6bc9d15c93a4920d6f"}, + {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ad5e65b874b5e56bd942546ea7ba9dd1d6a25121db1c517700f1c9de91b28518"}, + {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17fe4b2c844bbf5f0ece69cfd959fa02957c61317b2161763950d88fed8e13b9"}, + {file = "pendulum-3.0.0-cp312-none-win_amd64.whl", hash = "sha256:78f8f4e7efe5066aca24a7a57511b9c2119f5c2b5eb81c46ff9222ce11e0a7a5"}, + {file = "pendulum-3.0.0-cp312-none-win_arm64.whl", hash = "sha256:28f49d8d1e32aae9c284a90b6bb3873eee15ec6e1d9042edd611b22a94ac462f"}, + {file = "pendulum-3.0.0-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:d4e2512f4e1a4670284a153b214db9719eb5d14ac55ada5b76cbdb8c5c00399d"}, + {file = "pendulum-3.0.0-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:3d897eb50883cc58d9b92f6405245f84b9286cd2de6e8694cb9ea5cb15195a32"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e169cc2ca419517f397811bbe4589cf3cd13fca6dc38bb352ba15ea90739ebb"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17c3084a4524ebefd9255513692f7e7360e23c8853dc6f10c64cc184e1217ab"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:826d6e258052715f64d05ae0fc9040c0151e6a87aae7c109ba9a0ed930ce4000"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2aae97087872ef152a0c40e06100b3665d8cb86b59bc8471ca7c26132fccd0f"}, + {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ac65eeec2250d03106b5e81284ad47f0d417ca299a45e89ccc69e36130ca8bc7"}, + {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a5346d08f3f4a6e9e672187faa179c7bf9227897081d7121866358af369f44f9"}, + {file = "pendulum-3.0.0-cp37-none-win_amd64.whl", hash = "sha256:235d64e87946d8f95c796af34818c76e0f88c94d624c268693c85b723b698aa9"}, + {file = "pendulum-3.0.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:6a881d9c2a7f85bc9adafcfe671df5207f51f5715ae61f5d838b77a1356e8b7b"}, + {file = "pendulum-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d7762d2076b9b1cb718a6631ad6c16c23fc3fac76cbb8c454e81e80be98daa34"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e8e36a8130819d97a479a0e7bf379b66b3b1b520e5dc46bd7eb14634338df8c"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7dc843253ac373358ffc0711960e2dd5b94ab67530a3e204d85c6e8cb2c5fa10"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a78ad3635d609ceb1e97d6aedef6a6a6f93433ddb2312888e668365908c7120"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a137e9e0d1f751e60e67d11fc67781a572db76b2296f7b4d44554761049d6"}, + {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c95984037987f4a457bb760455d9ca80467be792236b69d0084f228a8ada0162"}, + {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d29c6e578fe0f893766c0d286adbf0b3c726a4e2341eba0917ec79c50274ec16"}, + {file = "pendulum-3.0.0-cp38-none-win_amd64.whl", hash = "sha256:deaba8e16dbfcb3d7a6b5fabdd5a38b7c982809567479987b9c89572df62e027"}, + {file = "pendulum-3.0.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b11aceea5b20b4b5382962b321dbc354af0defe35daa84e9ff3aae3c230df694"}, + {file = "pendulum-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a90d4d504e82ad236afac9adca4d6a19e4865f717034fc69bafb112c320dcc8f"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:825799c6b66e3734227756fa746cc34b3549c48693325b8b9f823cb7d21b19ac"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad769e98dc07972e24afe0cff8d365cb6f0ebc7e65620aa1976fcfbcadc4c6f3"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6fc26907eb5fb8cc6188cc620bc2075a6c534d981a2f045daa5f79dfe50d512"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c717eab1b6d898c00a3e0fa7781d615b5c5136bbd40abe82be100bb06df7a56"}, + {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3ddd1d66d1a714ce43acfe337190be055cdc221d911fc886d5a3aae28e14b76d"}, + {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:822172853d7a9cf6da95d7b66a16c7160cb99ae6df55d44373888181d7a06edc"}, + {file = "pendulum-3.0.0-cp39-none-win_amd64.whl", hash = "sha256:840de1b49cf1ec54c225a2a6f4f0784d50bd47f68e41dc005b7f67c7d5b5f3ae"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3b1f74d1e6ffe5d01d6023870e2ce5c2191486928823196f8575dcc786e107b1"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:729e9f93756a2cdfa77d0fc82068346e9731c7e884097160603872686e570f07"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e586acc0b450cd21cbf0db6bae386237011b75260a3adceddc4be15334689a9a"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22e7944ffc1f0099a79ff468ee9630c73f8c7835cd76fdb57ef7320e6a409df4"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fa30af36bd8e50686846bdace37cf6707bdd044e5cb6e1109acbad3277232e04"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:440215347b11914ae707981b9a57ab9c7b6983ab0babde07063c6ee75c0dc6e7"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:314c4038dc5e6a52991570f50edb2f08c339debdf8cea68ac355b32c4174e820"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5acb1d386337415f74f4d1955c4ce8d0201978c162927d07df8eb0692b2d8533"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a789e12fbdefaffb7b8ac67f9d8f22ba17a3050ceaaa635cd1cc4645773a4b1e"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:860aa9b8a888e5913bd70d819306749e5eb488e6b99cd6c47beb701b22bdecf5"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5ebc65ea033ef0281368217fbf59f5cb05b338ac4dd23d60959c7afcd79a60a0"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d9fef18ab0386ef6a9ac7bad7e43ded42c83ff7ad412f950633854f90d59afa8"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1c134ba2f0571d0b68b83f6972e2307a55a5a849e7dac8505c715c531d2a8795"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:385680812e7e18af200bb9b4a49777418c32422d05ad5a8eb85144c4a285907b"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eec91cd87c59fb32ec49eb722f375bd58f4be790cae11c1b70fac3ee4f00da0"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4386bffeca23c4b69ad50a36211f75b35a4deb6210bdca112ac3043deb7e494a"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dfbcf1661d7146d7698da4b86e7f04814221081e9fe154183e34f4c5f5fa3bf8"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:04a1094a5aa1daa34a6b57c865b25f691848c61583fb22722a4df5699f6bf74c"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5b0ec85b9045bd49dd3a3493a5e7ddfd31c36a2a60da387c419fa04abcaecb23"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0a15b90129765b705eb2039062a6daf4d22c4e28d1a54fa260892e8c3ae6e157"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:bb8f6d7acd67a67d6fedd361ad2958ff0539445ef51cbe8cd288db4306503cd0"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd69b15374bef7e4b4440612915315cc42e8575fcda2a3d7586a0d88192d0c88"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc00f8110db6898360c53c812872662e077eaf9c75515d53ecc65d886eec209a"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:83a44e8b40655d0ba565a5c3d1365d27e3e6778ae2a05b69124db9e471255c4a"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1a3604e9fbc06b788041b2a8b78f75c243021e0f512447806a6d37ee5214905d"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:92c307ae7accebd06cbae4729f0ba9fa724df5f7d91a0964b1b972a22baa482b"}, + {file = "pendulum-3.0.0.tar.gz", hash = "sha256:5d034998dea404ec31fae27af6b22cff1708f830a1ed7353be4d1019bb9f584e"}, ] [package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" +python-dateutil = ">=2.6" +tzdata = ">=2020.1" + +[package.extras] +test = ["time-machine (>=2.6.0)"] [[package]] name = "pexpect" -version = "4.8.0" +version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" files = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, ] [package.dependencies] ptyprocess = ">=0.5" -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -optional = false -python-versions = "*" -files = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] - [[package]] name = "pillow" -version = "10.0.1" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = true python-versions = ">=3.8" files = [ - {file = "Pillow-10.0.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:8f06be50669087250f319b706decf69ca71fdecd829091a37cc89398ca4dc17a"}, - {file = "Pillow-10.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50bd5f1ebafe9362ad622072a1d2f5850ecfa44303531ff14353a4059113b12d"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6a90167bcca1216606223a05e2cf991bb25b14695c518bc65639463d7db722d"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11c9102c56ffb9ca87134bd025a43d2aba3f1155f508eff88f694b33a9c6d19"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:186f7e04248103482ea6354af6d5bcedb62941ee08f7f788a1c7707bc720c66f"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0462b1496505a3462d0f35dc1c4d7b54069747d65d00ef48e736acda2c8cbdff"}, - {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d889b53ae2f030f756e61a7bff13684dcd77e9af8b10c6048fb2c559d6ed6eaf"}, - {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:552912dbca585b74d75279a7570dd29fa43b6d93594abb494ebb31ac19ace6bd"}, - {file = "Pillow-10.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:787bb0169d2385a798888e1122c980c6eff26bf941a8ea79747d35d8f9210ca0"}, - {file = "Pillow-10.0.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1"}, - {file = "Pillow-10.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d7e91b4379f7a76b31c2dda84ab9e20c6220488e50f7822e59dac36b0cd92b1"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e9adb3f22d4c416e7cd79b01375b17159d6990003633ff1d8377e21b7f1b21"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93139acd8109edcdeffd85e3af8ae7d88b258b3a1e13a038f542b79b6d255c54"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:92a23b0431941a33242b1f0ce6c88a952e09feeea9af4e8be48236a68ffe2205"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cbe68deb8580462ca0d9eb56a81912f59eb4542e1ef8f987405e35a0179f4ea2"}, - {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:522ff4ac3aaf839242c6f4e5b406634bfea002469656ae8358644fc6c4856a3b"}, - {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:84efb46e8d881bb06b35d1d541aa87f574b58e87f781cbba8d200daa835b42e1"}, - {file = "Pillow-10.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:898f1d306298ff40dc1b9ca24824f0488f6f039bc0e25cfb549d3195ffa17088"}, - {file = "Pillow-10.0.1-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:bcf1207e2f2385a576832af02702de104be71301c2696d0012b1b93fe34aaa5b"}, - {file = "Pillow-10.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d6c9049c6274c1bb565021367431ad04481ebb54872edecfcd6088d27edd6ed"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28444cb6ad49726127d6b340217f0627abc8732f1194fd5352dec5e6a0105635"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de596695a75496deb3b499c8c4f8e60376e0516e1a774e7bc046f0f48cd620ad"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:2872f2d7846cf39b3dbff64bc1104cc48c76145854256451d33c5faa55c04d1a"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4ce90f8a24e1c15465048959f1e94309dfef93af272633e8f37361b824532e91"}, - {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ee7810cf7c83fa227ba9125de6084e5e8b08c59038a7b2c9045ef4dde61663b4"}, - {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1be1c872b9b5fcc229adeadbeb51422a9633abd847c0ff87dc4ef9bb184ae08"}, - {file = "Pillow-10.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:98533fd7fa764e5f85eebe56c8e4094db912ccbe6fbf3a58778d543cadd0db08"}, - {file = "Pillow-10.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:764d2c0daf9c4d40ad12fbc0abd5da3af7f8aa11daf87e4fa1b834000f4b6b0a"}, - {file = "Pillow-10.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fcb59711009b0168d6ee0bd8fb5eb259c4ab1717b2f538bbf36bacf207ef7a68"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:697a06bdcedd473b35e50a7e7506b1d8ceb832dc238a336bd6f4f5aa91a4b500"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f665d1e6474af9f9da5e86c2a3a2d2d6204e04d5af9c06b9d42afa6ebde3f21"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:2fa6dd2661838c66f1a5473f3b49ab610c98a128fc08afbe81b91a1f0bf8c51d"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:3a04359f308ebee571a3127fdb1bd01f88ba6f6fb6d087f8dd2e0d9bff43f2a7"}, - {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:723bd25051454cea9990203405fa6b74e043ea76d4968166dfd2569b0210886a"}, - {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:71671503e3015da1b50bd18951e2f9daf5b6ffe36d16f1eb2c45711a301521a7"}, - {file = "Pillow-10.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:44e7e4587392953e5e251190a964675f61e4dae88d1e6edbe9f36d6243547ff3"}, - {file = "Pillow-10.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:3855447d98cced8670aaa63683808df905e956f00348732448b5a6df67ee5849"}, - {file = "Pillow-10.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed2d9c0704f2dc4fa980b99d565c0c9a543fe5101c25b3d60488b8ba80f0cce1"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5bb289bb835f9fe1a1e9300d011eef4d69661bb9b34d5e196e5e82c4cb09b37"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0d3e54ab1df9df51b914b2233cf779a5a10dfd1ce339d0421748232cea9876"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:2cc6b86ece42a11f16f55fe8903595eff2b25e0358dec635d0a701ac9586588f"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ca26ba5767888c84bf5a0c1a32f069e8204ce8c21d00a49c90dabeba00ce0145"}, - {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f0b4b06da13275bc02adfeb82643c4a6385bd08d26f03068c2796f60d125f6f2"}, - {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bc2e3069569ea9dbe88d6b8ea38f439a6aad8f6e7a6283a38edf61ddefb3a9bf"}, - {file = "Pillow-10.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8b451d6ead6e3500b6ce5c7916a43d8d8d25ad74b9102a629baccc0808c54971"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:32bec7423cdf25c9038fef614a853c9d25c07590e1a870ed471f47fb80b244db"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cf63d2c6928b51d35dfdbda6f2c1fddbe51a6bc4a9d4ee6ea0e11670dd981e"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f6d3d4c905e26354e8f9d82548475c46d8e0889538cb0657aa9c6f0872a37aa4"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:847e8d1017c741c735d3cd1883fa7b03ded4f825a6e5fcb9378fd813edee995f"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7f771e7219ff04b79e231d099c0a28ed83aa82af91fd5fa9fdb28f5b8d5addaf"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459307cacdd4138edee3875bbe22a2492519e060660eaf378ba3b405d1c66317"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b059ac2c4c7a97daafa7dc850b43b2d3667def858a4f112d1aa082e5c3d6cf7d"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6caf3cd38449ec3cd8a68b375e0c6fe4b6fd04edb6c9766b55ef84a6e8ddf2d"}, - {file = "Pillow-10.0.1.tar.gz", hash = "sha256:d72967b06be9300fed5cfbc8b5bafceec48bf7cdc7dab66b1d2549035287191d"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, ] +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + [[package]] name = "platformdirs" -version = "3.10.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] @@ -1987,13 +2072,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prompt-toolkit" -version = "3.0.39" +version = "3.0.47" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, - {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, ] [package.dependencies] @@ -2001,25 +2086,28 @@ wcwidth = "*" [[package]] name = "psutil" -version = "5.9.5" +version = "6.0.0" description = "Cross-platform lib for process and system monitoring in Python." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, - {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, - {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, - {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, - {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, - {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, - {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, - {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, ] [package.extras] @@ -2071,63 +2159,64 @@ test = ["pytest"] [[package]] name = "pybtex-docutils" -version = "1.0.2" +version = "1.0.3" description = "A docutils backend for pybtex." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pybtex-docutils-1.0.2.tar.gz", hash = "sha256:43aa353b6d498fd5ac30f0073a98e332d061d34fe619d3d50d1761f8fd4aa016"}, - {file = "pybtex_docutils-1.0.2-py3-none-any.whl", hash = "sha256:6f9e3c25a37bcaac8c4f69513272706ec6253bb708a93d8b4b173f43915ba239"}, + {file = "pybtex-docutils-1.0.3.tar.gz", hash = "sha256:3a7ebdf92b593e00e8c1c538aa9a20bca5d92d84231124715acc964d51d93c6b"}, + {file = "pybtex_docutils-1.0.3-py3-none-any.whl", hash = "sha256:8fd290d2ae48e32fcb54d86b0efb8d573198653c7e2447d5bec5847095f430b9"}, ] [package.dependencies] -docutils = ">=0.8" +docutils = ">=0.14" pybtex = ">=0.16" [[package]] name = "pycparser" -version = "2.21" +version = "2.22" description = "C parser in Python" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.8" files = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] [[package]] name = "pygments" -version = "2.16.1" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" -version = "2.17.5" +version = "3.2.5" description = "python code static checker" optional = false -python-versions = ">=3.7.2" +python-versions = ">=3.8.0" files = [ - {file = "pylint-2.17.5-py3-none-any.whl", hash = "sha256:73995fb8216d3bed149c8d51bba25b2c52a8251a2c8ac846ec668ce38fab5413"}, - {file = "pylint-2.17.5.tar.gz", hash = "sha256:f7b601cbc06fef7e62a754e2b41294c2aa31f1cb659624b9a85bcba29eaf8252"}, + {file = "pylint-3.2.5-py3-none-any.whl", hash = "sha256:32cd6c042b5004b8e857d727708720c54a676d1e22917cf1a2df9b4d4868abd6"}, + {file = "pylint-3.2.5.tar.gz", hash = "sha256:e9b7171e242dcc6ebd0aaa7540481d1a72860748a0a7816b8fe6cf6c80a6fe7e"}, ] [package.dependencies] -astroid = ">=2.15.6,<=2.17.0-dev0" +astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, + {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] -isort = ">=4.2.5,<6" +isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -2140,13 +2229,13 @@ testutils = ["gitpython (>3)"] [[package]] name = "pyparsing" -version = "3.0.9" +version = "3.1.2" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = true python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, ] [package.extras] @@ -2174,13 +2263,13 @@ files = [ [[package]] name = "pytest" -version = "7.4.0" +version = "7.4.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, - {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] @@ -2227,13 +2316,13 @@ pytest = ">=2.6.0" [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -2241,24 +2330,13 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2023.3" +version = "2024.1" description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, - {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, -] - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "*" files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] [[package]] @@ -2335,104 +2413,99 @@ files = [ [[package]] name = "pyzmq" -version = "25.1.1" +version = "26.0.3" description = "Python bindings for 0MQ" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:381469297409c5adf9a0e884c5eb5186ed33137badcbbb0560b86e910a2f1e76"}, - {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:955215ed0604dac5b01907424dfa28b40f2b2292d6493445dd34d0dfa72586a8"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:985bbb1316192b98f32e25e7b9958088431d853ac63aca1d2c236f40afb17c83"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:afea96f64efa98df4da6958bae37f1cbea7932c35878b185e5982821bc883369"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76705c9325d72a81155bb6ab48d4312e0032bf045fb0754889133200f7a0d849"}, - {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:77a41c26205d2353a4c94d02be51d6cbdf63c06fbc1295ea57dad7e2d3381b71"}, - {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:12720a53e61c3b99d87262294e2b375c915fea93c31fc2336898c26d7aed34cd"}, - {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:57459b68e5cd85b0be8184382cefd91959cafe79ae019e6b1ae6e2ba8a12cda7"}, - {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:292fe3fc5ad4a75bc8df0dfaee7d0babe8b1f4ceb596437213821f761b4589f9"}, - {file = "pyzmq-25.1.1-cp310-cp310-win32.whl", hash = "sha256:35b5ab8c28978fbbb86ea54958cd89f5176ce747c1fb3d87356cf698048a7790"}, - {file = "pyzmq-25.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:11baebdd5fc5b475d484195e49bae2dc64b94a5208f7c89954e9e354fc609d8f"}, - {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:d20a0ddb3e989e8807d83225a27e5c2eb2260eaa851532086e9e0fa0d5287d83"}, - {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e1c1be77bc5fb77d923850f82e55a928f8638f64a61f00ff18a67c7404faf008"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d89528b4943d27029a2818f847c10c2cecc79fa9590f3cb1860459a5be7933eb"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90f26dc6d5f241ba358bef79be9ce06de58d477ca8485e3291675436d3827cf8"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2b92812bd214018e50b6380ea3ac0c8bb01ac07fcc14c5f86a5bb25e74026e9"}, - {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:2f957ce63d13c28730f7fd6b72333814221c84ca2421298f66e5143f81c9f91f"}, - {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:047a640f5c9c6ade7b1cc6680a0e28c9dd5a0825135acbd3569cc96ea00b2505"}, - {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7f7e58effd14b641c5e4dec8c7dab02fb67a13df90329e61c869b9cc607ef752"}, - {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c2910967e6ab16bf6fbeb1f771c89a7050947221ae12a5b0b60f3bca2ee19bca"}, - {file = "pyzmq-25.1.1-cp311-cp311-win32.whl", hash = "sha256:76c1c8efb3ca3a1818b837aea423ff8a07bbf7aafe9f2f6582b61a0458b1a329"}, - {file = "pyzmq-25.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:44e58a0554b21fc662f2712814a746635ed668d0fbc98b7cb9d74cb798d202e6"}, - {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:e1ffa1c924e8c72778b9ccd386a7067cddf626884fd8277f503c48bb5f51c762"}, - {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1af379b33ef33757224da93e9da62e6471cf4a66d10078cf32bae8127d3d0d4a"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cff084c6933680d1f8b2f3b4ff5bbb88538a4aac00d199ac13f49d0698727ecb"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2400a94f7dd9cb20cd012951a0cbf8249e3d554c63a9c0cdfd5cbb6c01d2dec"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d81f1ddae3858b8299d1da72dd7d19dd36aab654c19671aa8a7e7fb02f6638a"}, - {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:255ca2b219f9e5a3a9ef3081512e1358bd4760ce77828e1028b818ff5610b87b"}, - {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a882ac0a351288dd18ecae3326b8a49d10c61a68b01419f3a0b9a306190baf69"}, - {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:724c292bb26365659fc434e9567b3f1adbdb5e8d640c936ed901f49e03e5d32e"}, - {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ca1ed0bb2d850aa8471387882247c68f1e62a4af0ce9c8a1dbe0d2bf69e41fb"}, - {file = "pyzmq-25.1.1-cp312-cp312-win32.whl", hash = "sha256:b3451108ab861040754fa5208bca4a5496c65875710f76789a9ad27c801a0075"}, - {file = "pyzmq-25.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:eadbefd5e92ef8a345f0525b5cfd01cf4e4cc651a2cffb8f23c0dd184975d787"}, - {file = "pyzmq-25.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:db0b2af416ba735c6304c47f75d348f498b92952f5e3e8bff449336d2728795d"}, - {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c133e93b405eb0d36fa430c94185bdd13c36204a8635470cccc200723c13bb"}, - {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:273bc3959bcbff3f48606b28229b4721716598d76b5aaea2b4a9d0ab454ec062"}, - {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cbc8df5c6a88ba5ae385d8930da02201165408dde8d8322072e3e5ddd4f68e22"}, - {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:18d43df3f2302d836f2a56f17e5663e398416e9dd74b205b179065e61f1a6edf"}, - {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:73461eed88a88c866656e08f89299720a38cb4e9d34ae6bf5df6f71102570f2e"}, - {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:34c850ce7976d19ebe7b9d4b9bb8c9dfc7aac336c0958e2651b88cbd46682123"}, - {file = "pyzmq-25.1.1-cp36-cp36m-win32.whl", hash = "sha256:d2045d6d9439a0078f2a34b57c7b18c4a6aef0bee37f22e4ec9f32456c852c71"}, - {file = "pyzmq-25.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:458dea649f2f02a0b244ae6aef8dc29325a2810aa26b07af8374dc2a9faf57e3"}, - {file = "pyzmq-25.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7cff25c5b315e63b07a36f0c2bab32c58eafbe57d0dce61b614ef4c76058c115"}, - {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1579413ae492b05de5a6174574f8c44c2b9b122a42015c5292afa4be2507f28"}, - {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3d0a409d3b28607cc427aa5c30a6f1e4452cc44e311f843e05edb28ab5e36da0"}, - {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21eb4e609a154a57c520e3d5bfa0d97e49b6872ea057b7c85257b11e78068222"}, - {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:034239843541ef7a1aee0c7b2cb7f6aafffb005ede965ae9cbd49d5ff4ff73cf"}, - {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f8115e303280ba09f3898194791a153862cbf9eef722ad8f7f741987ee2a97c7"}, - {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1a5d26fe8f32f137e784f768143728438877d69a586ddeaad898558dc971a5ae"}, - {file = "pyzmq-25.1.1-cp37-cp37m-win32.whl", hash = "sha256:f32260e556a983bc5c7ed588d04c942c9a8f9c2e99213fec11a031e316874c7e"}, - {file = "pyzmq-25.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:abf34e43c531bbb510ae7e8f5b2b1f2a8ab93219510e2b287a944432fad135f3"}, - {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:87e34f31ca8f168c56d6fbf99692cc8d3b445abb5bfd08c229ae992d7547a92a"}, - {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c9c6c9b2c2f80747a98f34ef491c4d7b1a8d4853937bb1492774992a120f475d"}, - {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5619f3f5a4db5dbb572b095ea3cb5cc035335159d9da950830c9c4db2fbb6995"}, - {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a34d2395073ef862b4032343cf0c32a712f3ab49d7ec4f42c9661e0294d106f"}, - {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f0e6b78220aba09815cd1f3a32b9c7cb3e02cb846d1cfc526b6595f6046618"}, - {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3669cf8ee3520c2f13b2e0351c41fea919852b220988d2049249db10046a7afb"}, - {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2d163a18819277e49911f7461567bda923461c50b19d169a062536fffe7cd9d2"}, - {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:df27ffddff4190667d40de7beba4a950b5ce78fe28a7dcc41d6f8a700a80a3c0"}, - {file = "pyzmq-25.1.1-cp38-cp38-win32.whl", hash = "sha256:a382372898a07479bd34bda781008e4a954ed8750f17891e794521c3e21c2e1c"}, - {file = "pyzmq-25.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:52533489f28d62eb1258a965f2aba28a82aa747202c8fa5a1c7a43b5db0e85c1"}, - {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:03b3f49b57264909aacd0741892f2aecf2f51fb053e7d8ac6767f6c700832f45"}, - {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:330f9e188d0d89080cde66dc7470f57d1926ff2fb5576227f14d5be7ab30b9fa"}, - {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2ca57a5be0389f2a65e6d3bb2962a971688cbdd30b4c0bd188c99e39c234f414"}, - {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d457aed310f2670f59cc5b57dcfced452aeeed77f9da2b9763616bd57e4dbaae"}, - {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c56d748ea50215abef7030c72b60dd723ed5b5c7e65e7bc2504e77843631c1a6"}, - {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8f03d3f0d01cb5a018debeb412441996a517b11c5c17ab2001aa0597c6d6882c"}, - {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:820c4a08195a681252f46926de10e29b6bbf3e17b30037bd4250d72dd3ddaab8"}, - {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17ef5f01d25b67ca8f98120d5fa1d21efe9611604e8eb03a5147360f517dd1e2"}, - {file = "pyzmq-25.1.1-cp39-cp39-win32.whl", hash = "sha256:04ccbed567171579ec2cebb9c8a3e30801723c575601f9a990ab25bcac6b51e2"}, - {file = "pyzmq-25.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:e61f091c3ba0c3578411ef505992d356a812fb200643eab27f4f70eed34a29ef"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ade6d25bb29c4555d718ac6d1443a7386595528c33d6b133b258f65f963bb0f6"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0c95ddd4f6e9fca4e9e3afaa4f9df8552f0ba5d1004e89ef0a68e1f1f9807c7"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48e466162a24daf86f6b5ca72444d2bf39a5e58da5f96370078be67c67adc978"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abc719161780932c4e11aaebb203be3d6acc6b38d2f26c0f523b5b59d2fc1996"}, - {file = "pyzmq-25.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ccf825981640b8c34ae54231b7ed00271822ea1c6d8ba1090ebd4943759abf5"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c2f20ce161ebdb0091a10c9ca0372e023ce24980d0e1f810f519da6f79c60800"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:deee9ca4727f53464daf089536e68b13e6104e84a37820a88b0a057b97bba2d2"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aa8d6cdc8b8aa19ceb319aaa2b660cdaccc533ec477eeb1309e2a291eaacc43a"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019e59ef5c5256a2c7378f2fb8560fc2a9ff1d315755204295b2eab96b254d0a"}, - {file = "pyzmq-25.1.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b9af3757495c1ee3b5c4e945c1df7be95562277c6e5bccc20a39aec50f826cd0"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:548d6482dc8aadbe7e79d1b5806585c8120bafa1ef841167bc9090522b610fa6"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:057e824b2aae50accc0f9a0570998adc021b372478a921506fddd6c02e60308e"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2243700cc5548cff20963f0ca92d3e5e436394375ab8a354bbea2b12911b20b0"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79986f3b4af059777111409ee517da24a529bdbd46da578b33f25580adcff728"}, - {file = "pyzmq-25.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:11d58723d44d6ed4dd677c5615b2ffb19d5c426636345567d6af82be4dff8a55"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:49d238cf4b69652257db66d0c623cd3e09b5d2e9576b56bc067a396133a00d4a"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fedbdc753827cf014c01dbbee9c3be17e5a208dcd1bf8641ce2cd29580d1f0d4"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc16ac425cc927d0a57d242589f87ee093884ea4804c05a13834d07c20db203c"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11c1d2aed9079c6b0c9550a7257a836b4a637feb334904610f06d70eb44c56d2"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e8a701123029cc240cea61dd2d16ad57cab4691804143ce80ecd9286b464d180"}, - {file = "pyzmq-25.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:61706a6b6c24bdece85ff177fec393545a3191eeda35b07aaa1458a027ad1304"}, - {file = "pyzmq-25.1.1.tar.gz", hash = "sha256:259c22485b71abacdfa8bf79720cd7bcf4b9d128b30ea554f01ae71fdbfdaa23"}, + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:44dd6fc3034f1eaa72ece33588867df9e006a7303725a12d64c3dff92330f625"}, + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:acb704195a71ac5ea5ecf2811c9ee19ecdc62b91878528302dd0be1b9451cc90"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbb9c997932473a27afa93954bb77a9f9b786b4ccf718d903f35da3232317de"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bcb34f869d431799c3ee7d516554797f7760cb2198ecaa89c3f176f72d062be"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ece17ec5f20d7d9b442e5174ae9f020365d01ba7c112205a4d59cf19dc38ee"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ba6e5e6588e49139a0979d03a7deb9c734bde647b9a8808f26acf9c547cab1bf"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3bf8b000a4e2967e6dfdd8656cd0757d18c7e5ce3d16339e550bd462f4857e59"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2136f64fbb86451dbbf70223635a468272dd20075f988a102bf8a3f194a411dc"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e8918973fbd34e7814f59143c5f600ecd38b8038161239fd1a3d33d5817a38b8"}, + {file = "pyzmq-26.0.3-cp310-cp310-win32.whl", hash = "sha256:0aaf982e68a7ac284377d051c742610220fd06d330dcd4c4dbb4cdd77c22a537"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:f1a9b7d00fdf60b4039f4455afd031fe85ee8305b019334b72dcf73c567edc47"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:80b12f25d805a919d53efc0a5ad7c0c0326f13b4eae981a5d7b7cc343318ebb7"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:a72a84570f84c374b4c287183debc776dc319d3e8ce6b6a0041ce2e400de3f32"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ca684ee649b55fd8f378127ac8462fb6c85f251c2fb027eb3c887e8ee347bcd"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e222562dc0f38571c8b1ffdae9d7adb866363134299264a1958d077800b193b7"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f17cde1db0754c35a91ac00b22b25c11da6eec5746431d6e5092f0cd31a3fea9"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7c0c0b3244bb2275abe255d4a30c050d541c6cb18b870975553f1fb6f37527"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac97a21de3712afe6a6c071abfad40a6224fd14fa6ff0ff8d0c6e6cd4e2f807a"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:88b88282e55fa39dd556d7fc04160bcf39dea015f78e0cecec8ff4f06c1fc2b5"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:72b67f966b57dbd18dcc7efbc1c7fc9f5f983e572db1877081f075004614fcdd"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4b6cecbbf3b7380f3b61de3a7b93cb721125dc125c854c14ddc91225ba52f83"}, + {file = "pyzmq-26.0.3-cp311-cp311-win32.whl", hash = "sha256:eed56b6a39216d31ff8cd2f1d048b5bf1700e4b32a01b14379c3b6dde9ce3aa3"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:3191d312c73e3cfd0f0afdf51df8405aafeb0bad71e7ed8f68b24b63c4f36500"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:b6907da3017ef55139cf0e417c5123a84c7332520e73a6902ff1f79046cd3b94"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:068ca17214038ae986d68f4a7021f97e187ed278ab6dccb79f837d765a54d753"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7821d44fe07335bea256b9f1f41474a642ca55fa671dfd9f00af8d68a920c2d4"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb438a26d87c123bb318e5f2b3d86a36060b01f22fbdffd8cf247d52f7c9a2b"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69ea9d6d9baa25a4dc9cef5e2b77b8537827b122214f210dd925132e34ae9b12"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7daa3e1369355766dea11f1d8ef829905c3b9da886ea3152788dc25ee6079e02"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6ca7a9a06b52d0e38ccf6bca1aeff7be178917893f3883f37b75589d42c4ac20"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1b7d0e124948daa4d9686d421ef5087c0516bc6179fdcf8828b8444f8e461a77"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e746524418b70f38550f2190eeee834db8850088c834d4c8406fbb9bc1ae10b2"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6b3146f9ae6af82c47a5282ac8803523d381b3b21caeae0327ed2f7ecb718798"}, + {file = "pyzmq-26.0.3-cp312-cp312-win32.whl", hash = "sha256:2b291d1230845871c00c8462c50565a9cd6026fe1228e77ca934470bb7d70ea0"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:926838a535c2c1ea21c903f909a9a54e675c2126728c21381a94ddf37c3cbddf"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:5bf6c237f8c681dfb91b17f8435b2735951f0d1fad10cc5dfd96db110243370b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c0991f5a96a8e620f7691e61178cd8f457b49e17b7d9cfa2067e2a0a89fc1d5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dbf012d8fcb9f2cf0643b65df3b355fdd74fc0035d70bb5c845e9e30a3a4654b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:01fbfbeb8249a68d257f601deb50c70c929dc2dfe683b754659569e502fbd3aa"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c8eb19abe87029c18f226d42b8a2c9efdd139d08f8bf6e085dd9075446db450"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5344b896e79800af86ad643408ca9aa303a017f6ebff8cee5a3163c1e9aec987"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:204e0f176fd1d067671157d049466869b3ae1fc51e354708b0dc41cf94e23a3a"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a42db008d58530efa3b881eeee4991146de0b790e095f7ae43ba5cc612decbc5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win32.whl", hash = "sha256:8d7a498671ca87e32b54cb47c82a92b40130a26c5197d392720a1bce1b3c77cf"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:3b4032a96410bdc760061b14ed6a33613ffb7f702181ba999df5d16fb96ba16a"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:2cc4e280098c1b192c42a849de8de2c8e0f3a84086a76ec5b07bfee29bda7d18"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bde86a2ed3ce587fa2b207424ce15b9a83a9fa14422dcc1c5356a13aed3df9d"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:34106f68e20e6ff253c9f596ea50397dbd8699828d55e8fa18bd4323d8d966e6"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ebbbd0e728af5db9b04e56389e2299a57ea8b9dd15c9759153ee2455b32be6ad"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6b1d1c631e5940cac5a0b22c5379c86e8df6a4ec277c7a856b714021ab6cfad"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e891ce81edd463b3b4c3b885c5603c00141151dd9c6936d98a680c8c72fe5c67"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9b273ecfbc590a1b98f014ae41e5cf723932f3b53ba9367cfb676f838038b32c"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b32bff85fb02a75ea0b68f21e2412255b5731f3f389ed9aecc13a6752f58ac97"}, + {file = "pyzmq-26.0.3-cp38-cp38-win32.whl", hash = "sha256:f6c21c00478a7bea93caaaef9e7629145d4153b15a8653e8bb4609d4bc70dbfc"}, + {file = "pyzmq-26.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:3401613148d93ef0fd9aabdbddb212de3db7a4475367f49f590c837355343972"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:2ed8357f4c6e0daa4f3baf31832df8a33334e0fe5b020a61bc8b345a3db7a606"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c1c8f2a2ca45292084c75bb6d3a25545cff0ed931ed228d3a1810ae3758f975f"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b63731993cdddcc8e087c64e9cf003f909262b359110070183d7f3025d1c56b5"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b3cd31f859b662ac5d7f4226ec7d8bd60384fa037fc02aee6ff0b53ba29a3ba8"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:115f8359402fa527cf47708d6f8a0f8234f0e9ca0cab7c18c9c189c194dbf620"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:715bdf952b9533ba13dfcf1f431a8f49e63cecc31d91d007bc1deb914f47d0e4"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e1258c639e00bf5e8a522fec6c3eaa3e30cf1c23a2f21a586be7e04d50c9acab"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:15c59e780be8f30a60816a9adab900c12a58d79c1ac742b4a8df044ab2a6d920"}, + {file = "pyzmq-26.0.3-cp39-cp39-win32.whl", hash = "sha256:d0cdde3c78d8ab5b46595054e5def32a755fc028685add5ddc7403e9f6de9879"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:ce828058d482ef860746bf532822842e0ff484e27f540ef5c813d516dd8896d2"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:788f15721c64109cf720791714dc14afd0f449d63f3a5487724f024345067381"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c18645ef6294d99b256806e34653e86236eb266278c8ec8112622b61db255de"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e6bc96ebe49604df3ec2c6389cc3876cabe475e6bfc84ced1bf4e630662cb35"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:971e8990c5cc4ddcff26e149398fc7b0f6a042306e82500f5e8db3b10ce69f84"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8416c23161abd94cc7da80c734ad7c9f5dbebdadfdaa77dad78244457448223"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:082a2988364b60bb5de809373098361cf1dbb239623e39e46cb18bc035ed9c0c"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d57dfbf9737763b3a60d26e6800e02e04284926329aee8fb01049635e957fe81"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:77a85dca4c2430ac04dc2a2185c2deb3858a34fe7f403d0a946fa56970cf60a1"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c82a6d952a1d555bf4be42b6532927d2a5686dd3c3e280e5f63225ab47ac1f5"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4496b1282c70c442809fc1b151977c3d967bfb33e4e17cedbf226d97de18f709"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e4946d6bdb7ba972dfda282f9127e5756d4f299028b1566d1245fa0d438847e6"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03c0ae165e700364b266876d712acb1ac02693acd920afa67da2ebb91a0b3c09"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:3e3070e680f79887d60feeda051a58d0ac36622e1759f305a41059eff62c6da7"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6ca08b840fe95d1c2bd9ab92dac5685f949fc6f9ae820ec16193e5ddf603c3b2"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e76654e9dbfb835b3518f9938e565c7806976c07b37c33526b574cc1a1050480"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:871587bdadd1075b112e697173e946a07d722459d20716ceb3d1bd6c64bd08ce"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d0a2d1bd63a4ad79483049b26514e70fa618ce6115220da9efdff63688808b17"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0270b49b6847f0d106d64b5086e9ad5dc8a902413b5dbbb15d12b60f9c1747a4"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:703c60b9910488d3d0954ca585c34f541e506a091a41930e663a098d3b794c67"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74423631b6be371edfbf7eabb02ab995c2563fee60a80a30829176842e71722a"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4adfbb5451196842a88fda3612e2c0414134874bffb1c2ce83ab4242ec9e027d"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3516119f4f9b8671083a70b6afaa0a070f5683e431ab3dc26e9215620d7ca1ad"}, + {file = "pyzmq-26.0.3.tar.gz", hash = "sha256:dba7d9f2e047dfa2bca3b01f4f84aa5246725203d6284e3790f2ca15fba6b40a"}, ] [package.dependencies] @@ -2440,13 +2513,13 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "referencing" -version = "0.30.2" +version = "0.35.1" description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, - {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, ] [package.dependencies] @@ -2455,13 +2528,13 @@ rpds-py = ">=0.7.0" [[package]] name = "requests" -version = "2.31.0" +version = "2.32.3" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -2488,154 +2561,159 @@ files = [ [package.dependencies] commonmark = ">=0.9.0,<0.10.0" pygments = ">=2.6.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] [[package]] name = "rpds-py" -version = "0.9.2" +version = "0.19.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"}, - {file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6"}, - {file = "rpds_py-0.9.2-cp310-none-win32.whl", hash = "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764"}, - {file = "rpds_py-0.9.2-cp310-none-win_amd64.whl", hash = "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e"}, - {file = "rpds_py-0.9.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3"}, - {file = "rpds_py-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de"}, - {file = "rpds_py-0.9.2-cp311-none-win32.whl", hash = "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab"}, - {file = "rpds_py-0.9.2-cp311-none-win_amd64.whl", hash = "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298"}, - {file = "rpds_py-0.9.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386"}, - {file = "rpds_py-0.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d"}, - {file = "rpds_py-0.9.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d"}, - {file = "rpds_py-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e"}, - {file = "rpds_py-0.9.2-cp38-none-win32.whl", hash = "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920"}, - {file = "rpds_py-0.9.2-cp38-none-win_amd64.whl", hash = "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044"}, - {file = "rpds_py-0.9.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260"}, - {file = "rpds_py-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26"}, - {file = "rpds_py-0.9.2-cp39-none-win32.whl", hash = "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0"}, - {file = "rpds_py-0.9.2-cp39-none-win_amd64.whl", hash = "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"}, - {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582"}, + {file = "rpds_py-0.19.0-cp310-none-win32.whl", hash = "sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336"}, + {file = "rpds_py-0.19.0-cp310-none-win_amd64.whl", hash = "sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952"}, + {file = "rpds_py-0.19.0-cp311-none-win32.whl", hash = "sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf"}, + {file = "rpds_py-0.19.0-cp311-none-win_amd64.whl", hash = "sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248"}, + {file = "rpds_py-0.19.0-cp312-none-win32.whl", hash = "sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600"}, + {file = "rpds_py-0.19.0-cp312-none-win_amd64.whl", hash = "sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae"}, + {file = "rpds_py-0.19.0-cp38-none-win32.whl", hash = "sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4"}, + {file = "rpds_py-0.19.0-cp38-none-win_amd64.whl", hash = "sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be"}, + {file = "rpds_py-0.19.0-cp39-none-win32.whl", hash = "sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb"}, + {file = "rpds_py-0.19.0-cp39-none-win_amd64.whl", hash = "sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521"}, + {file = "rpds_py-0.19.0.tar.gz", hash = "sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9"}, ] [[package]] name = "scipy" -version = "1.10.1" +version = "1.13.1" description = "Fundamental algorithms for scientific computing in Python" optional = false -python-versions = "<3.12,>=3.8" -files = [ - {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, - {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"}, - {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"}, - {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"}, - {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"}, - {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, - {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, +python-versions = ">=3.9" +files = [ + {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, + {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, + {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, + {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, + {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, + {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, + {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, + {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, + {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, + {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, + {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, + {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, + {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, + {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, + {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, + {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, + {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, + {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, + {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, + {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, + {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, + {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, + {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, + {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, + {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, ] [package.dependencies] -numpy = ">=1.19.5,<1.27.0" +numpy = ">=1.22.4,<2.3" [package.extras] -dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] -doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "six" @@ -2661,64 +2739,65 @@ files = [ [[package]] name = "soupsieve" -version = "2.4.1" +version = "2.5" description = "A modern CSS selector implementation for Beautiful Soup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, - {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] [[package]] name = "sphinx" -version = "4.5.0" +version = "7.3.7" description = "Python documentation generator" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, - {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, + {file = "sphinx-7.3.7-py3-none-any.whl", hash = "sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3"}, + {file = "sphinx-7.3.7.tar.gz", hash = "sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc"}, ] [package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" -imagesize = "*" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" -requests = ">=2.5.0" -snowballstemmer = ">=1.1" +alabaster = ">=0.7.14,<0.8.0" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.18.1,<0.22" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.14" +requests = ">=2.25.0" +snowballstemmer = ">=2.0" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" sphinxcontrib-jsmath = "*" sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" +sphinxcontrib-serializinghtml = ">=1.1.9" +tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] +lint = ["flake8 (>=3.5.0)", "importlib_metadata", "mypy (==1.9.0)", "pytest (>=6.0)", "ruff (==0.3.7)", "sphinx-lint", "tomli", "types-docutils", "types-requests"] +test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=6.0)", "setuptools (>=67.0)"] [[package]] name = "sphinx-rtd-theme" -version = "1.2.2" +version = "1.3.0" description = "Read the Docs theme for Sphinx" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "sphinx_rtd_theme-1.2.2-py2.py3-none-any.whl", hash = "sha256:6a7e7d8af34eb8fc57d52a09c6b6b9c46ff44aea5951bc831eeb9245378f3689"}, - {file = "sphinx_rtd_theme-1.2.2.tar.gz", hash = "sha256:01c5c5a72e2d025bd23d1f06c59a4831b06e6ce6c01fdd5ebfe9986c0a880fc7"}, + {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"}, + {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"}, ] [package.dependencies] docutils = "<0.19" -sphinx = ">=1.6,<7" +sphinx = ">=1.6,<8" sphinxcontrib-jquery = ">=4,<5" [package.extras] @@ -2726,17 +2805,18 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.4" +version = "1.0.8" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, - {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, + {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, + {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] @@ -2759,32 +2839,34 @@ Sphinx = ">=2.1" [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +version = "1.0.6" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, + {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, + {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.1" +version = "2.0.5" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, - {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, + {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, + {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] [[package]] @@ -2817,87 +2899,97 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +version = "1.0.7" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, + {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, + {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +version = "1.1.10" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, + {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, + {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sqlalchemy" -version = "1.4.49" +version = "1.4.52" description = "Database Abstraction Library" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "SQLAlchemy-1.4.49-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e126cf98b7fd38f1e33c64484406b78e937b1a280e078ef558b95bf5b6895f6"}, - {file = "SQLAlchemy-1.4.49-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:03db81b89fe7ef3857b4a00b63dedd632d6183d4ea5a31c5d8a92e000a41fc71"}, - {file = "SQLAlchemy-1.4.49-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:95b9df9afd680b7a3b13b38adf6e3a38995da5e162cc7524ef08e3be4e5ed3e1"}, - {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a63e43bf3f668c11bb0444ce6e809c1227b8f067ca1068898f3008a273f52b09"}, - {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f835c050ebaa4e48b18403bed2c0fda986525896efd76c245bdd4db995e51a4c"}, - {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c21b172dfb22e0db303ff6419451f0cac891d2e911bb9fbf8003d717f1bcf91"}, - {file = "SQLAlchemy-1.4.49-cp310-cp310-win32.whl", hash = "sha256:5fb1ebdfc8373b5a291485757bd6431de8d7ed42c27439f543c81f6c8febd729"}, - {file = "SQLAlchemy-1.4.49-cp310-cp310-win_amd64.whl", hash = "sha256:f8a65990c9c490f4651b5c02abccc9f113a7f56fa482031ac8cb88b70bc8ccaa"}, - {file = "SQLAlchemy-1.4.49-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8923dfdf24d5aa8a3adb59723f54118dd4fe62cf59ed0d0d65d940579c1170a4"}, - {file = "SQLAlchemy-1.4.49-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9ab2c507a7a439f13ca4499db6d3f50423d1d65dc9b5ed897e70941d9e135b0"}, - {file = "SQLAlchemy-1.4.49-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5debe7d49b8acf1f3035317e63d9ec8d5e4d904c6e75a2a9246a119f5f2fdf3d"}, - {file = "SQLAlchemy-1.4.49-cp311-cp311-win32.whl", hash = "sha256:82b08e82da3756765c2e75f327b9bf6b0f043c9c3925fb95fb51e1567fa4ee87"}, - {file = "SQLAlchemy-1.4.49-cp311-cp311-win_amd64.whl", hash = "sha256:171e04eeb5d1c0d96a544caf982621a1711d078dbc5c96f11d6469169bd003f1"}, - {file = "SQLAlchemy-1.4.49-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:36e58f8c4fe43984384e3fbe6341ac99b6b4e083de2fe838f0fdb91cebe9e9cb"}, - {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b31e67ff419013f99ad6f8fc73ee19ea31585e1e9fe773744c0f3ce58c039c30"}, - {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c14b29d9e1529f99efd550cd04dbb6db6ba5d690abb96d52de2bff4ed518bc95"}, - {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c40f3470e084d31247aea228aa1c39bbc0904c2b9ccbf5d3cfa2ea2dac06f26d"}, - {file = "SQLAlchemy-1.4.49-cp36-cp36m-win32.whl", hash = "sha256:706bfa02157b97c136547c406f263e4c6274a7b061b3eb9742915dd774bbc264"}, - {file = "SQLAlchemy-1.4.49-cp36-cp36m-win_amd64.whl", hash = "sha256:a7f7b5c07ae5c0cfd24c2db86071fb2a3d947da7bd487e359cc91e67ac1c6d2e"}, - {file = "SQLAlchemy-1.4.49-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:4afbbf5ef41ac18e02c8dc1f86c04b22b7a2125f2a030e25bbb4aff31abb224b"}, - {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24e300c0c2147484a002b175f4e1361f102e82c345bf263242f0449672a4bccf"}, - {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:201de072b818f8ad55c80d18d1a788729cccf9be6d9dc3b9d8613b053cd4836d"}, - {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653ed6817c710d0c95558232aba799307d14ae084cc9b1f4c389157ec50df5c"}, - {file = "SQLAlchemy-1.4.49-cp37-cp37m-win32.whl", hash = "sha256:647e0b309cb4512b1f1b78471fdaf72921b6fa6e750b9f891e09c6e2f0e5326f"}, - {file = "SQLAlchemy-1.4.49-cp37-cp37m-win_amd64.whl", hash = "sha256:ab73ed1a05ff539afc4a7f8cf371764cdf79768ecb7d2ec691e3ff89abbc541e"}, - {file = "SQLAlchemy-1.4.49-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:37ce517c011560d68f1ffb28af65d7e06f873f191eb3a73af5671e9c3fada08a"}, - {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1878ce508edea4a879015ab5215546c444233881301e97ca16fe251e89f1c55"}, - {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e8e608983e6f85d0852ca61f97e521b62e67969e6e640fe6c6b575d4db68557"}, - {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccf956da45290df6e809ea12c54c02ace7f8ff4d765d6d3dfb3655ee876ce58d"}, - {file = "SQLAlchemy-1.4.49-cp38-cp38-win32.whl", hash = "sha256:f167c8175ab908ce48bd6550679cc6ea20ae169379e73c7720a28f89e53aa532"}, - {file = "SQLAlchemy-1.4.49-cp38-cp38-win_amd64.whl", hash = "sha256:45806315aae81a0c202752558f0df52b42d11dd7ba0097bf71e253b4215f34f4"}, - {file = "SQLAlchemy-1.4.49-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:b6d0c4b15d65087738a6e22e0ff461b407533ff65a73b818089efc8eb2b3e1de"}, - {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a843e34abfd4c797018fd8d00ffffa99fd5184c421f190b6ca99def4087689bd"}, - {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1c890421651b45a681181301b3497e4d57c0d01dc001e10438a40e9a9c25ee77"}, - {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d26f280b8f0a8f497bc10573849ad6dc62e671d2468826e5c748d04ed9e670d5"}, - {file = "SQLAlchemy-1.4.49-cp39-cp39-win32.whl", hash = "sha256:ec2268de67f73b43320383947e74700e95c6770d0c68c4e615e9897e46296294"}, - {file = "SQLAlchemy-1.4.49-cp39-cp39-win_amd64.whl", hash = "sha256:bbdf16372859b8ed3f4d05f925a984771cd2abd18bd187042f24be4886c2a15f"}, - {file = "SQLAlchemy-1.4.49.tar.gz", hash = "sha256:06ff25cbae30c396c4b7737464f2a7fc37a67b7da409993b182b024cec80aed9"}, + {file = "SQLAlchemy-1.4.52-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:f68016f9a5713684c1507cc37133c28035f29925c75c0df2f9d0f7571e23720a"}, + {file = "SQLAlchemy-1.4.52-cp310-cp310-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24bb0f81fbbb13d737b7f76d1821ec0b117ce8cbb8ee5e8641ad2de41aa916d3"}, + {file = "SQLAlchemy-1.4.52-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e93983cc0d2edae253b3f2141b0a3fb07e41c76cd79c2ad743fc27eb79c3f6db"}, + {file = "SQLAlchemy-1.4.52-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:84e10772cfc333eb08d0b7ef808cd76e4a9a30a725fb62a0495877a57ee41d81"}, + {file = "SQLAlchemy-1.4.52-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:427988398d2902de042093d17f2b9619a5ebc605bf6372f7d70e29bde6736842"}, + {file = "SQLAlchemy-1.4.52-cp310-cp310-win32.whl", hash = "sha256:1296f2cdd6db09b98ceb3c93025f0da4835303b8ac46c15c2136e27ee4d18d94"}, + {file = "SQLAlchemy-1.4.52-cp310-cp310-win_amd64.whl", hash = "sha256:80e7f697bccc56ac6eac9e2df5c98b47de57e7006d2e46e1a3c17c546254f6ef"}, + {file = "SQLAlchemy-1.4.52-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2f251af4c75a675ea42766880ff430ac33291c8d0057acca79710f9e5a77383d"}, + {file = "SQLAlchemy-1.4.52-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb8f9e4c4718f111d7b530c4e6fb4d28f9f110eb82e7961412955b3875b66de0"}, + {file = "SQLAlchemy-1.4.52-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afb1672b57f58c0318ad2cff80b384e816735ffc7e848d8aa51e0b0fc2f4b7bb"}, + {file = "SQLAlchemy-1.4.52-cp311-cp311-win32.whl", hash = "sha256:6e41cb5cda641f3754568d2ed8962f772a7f2b59403b95c60c89f3e0bd25f15e"}, + {file = "SQLAlchemy-1.4.52-cp311-cp311-win_amd64.whl", hash = "sha256:5bed4f8c3b69779de9d99eb03fd9ab67a850d74ab0243d1be9d4080e77b6af12"}, + {file = "SQLAlchemy-1.4.52-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:49e3772eb3380ac88d35495843daf3c03f094b713e66c7d017e322144a5c6b7c"}, + {file = "SQLAlchemy-1.4.52-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:618827c1a1c243d2540314c6e100aee7af09a709bd005bae971686fab6723554"}, + {file = "SQLAlchemy-1.4.52-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de9acf369aaadb71a725b7e83a5ef40ca3de1cf4cdc93fa847df6b12d3cd924b"}, + {file = "SQLAlchemy-1.4.52-cp312-cp312-win32.whl", hash = "sha256:763bd97c4ebc74136ecf3526b34808c58945023a59927b416acebcd68d1fc126"}, + {file = "SQLAlchemy-1.4.52-cp312-cp312-win_amd64.whl", hash = "sha256:f12aaf94f4d9679ca475975578739e12cc5b461172e04d66f7a3c39dd14ffc64"}, + {file = "SQLAlchemy-1.4.52-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:853fcfd1f54224ea7aabcf34b227d2b64a08cbac116ecf376907968b29b8e763"}, + {file = "SQLAlchemy-1.4.52-cp36-cp36m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f98dbb8fcc6d1c03ae8ec735d3c62110949a3b8bc6e215053aa27096857afb45"}, + {file = "SQLAlchemy-1.4.52-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e135fff2e84103bc15c07edd8569612ce317d64bdb391f49ce57124a73f45c5"}, + {file = "SQLAlchemy-1.4.52-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5b5de6af8852500d01398f5047d62ca3431d1e29a331d0b56c3e14cb03f8094c"}, + {file = "SQLAlchemy-1.4.52-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3491c85df263a5c2157c594f54a1a9c72265b75d3777e61ee13c556d9e43ffc9"}, + {file = "SQLAlchemy-1.4.52-cp36-cp36m-win32.whl", hash = "sha256:427c282dd0deba1f07bcbf499cbcc9fe9a626743f5d4989bfdfd3ed3513003dd"}, + {file = "SQLAlchemy-1.4.52-cp36-cp36m-win_amd64.whl", hash = "sha256:ca5ce82b11731492204cff8845c5e8ca1a4bd1ade85e3b8fcf86e7601bfc6a39"}, + {file = "SQLAlchemy-1.4.52-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:29d4247313abb2015f8979137fe65f4eaceead5247d39603cc4b4a610936cd2b"}, + {file = "SQLAlchemy-1.4.52-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a752bff4796bf22803d052d4841ebc3c55c26fb65551f2c96e90ac7c62be763a"}, + {file = "SQLAlchemy-1.4.52-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ea11727feb2861deaa293c7971a4df57ef1c90e42cb53f0da40c3468388000"}, + {file = "SQLAlchemy-1.4.52-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d913f8953e098ca931ad7f58797f91deed26b435ec3756478b75c608aa80d139"}, + {file = "SQLAlchemy-1.4.52-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a251146b921725547ea1735b060a11e1be705017b568c9f8067ca61e6ef85f20"}, + {file = "SQLAlchemy-1.4.52-cp37-cp37m-win32.whl", hash = "sha256:1f8e1c6a6b7f8e9407ad9afc0ea41c1f65225ce505b79bc0342159de9c890782"}, + {file = "SQLAlchemy-1.4.52-cp37-cp37m-win_amd64.whl", hash = "sha256:346ed50cb2c30f5d7a03d888e25744154ceac6f0e6e1ab3bc7b5b77138d37710"}, + {file = "SQLAlchemy-1.4.52-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:4dae6001457d4497736e3bc422165f107ecdd70b0d651fab7f731276e8b9e12d"}, + {file = "SQLAlchemy-1.4.52-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5d2e08d79f5bf250afb4a61426b41026e448da446b55e4770c2afdc1e200fce"}, + {file = "SQLAlchemy-1.4.52-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bbce5dd7c7735e01d24f5a60177f3e589078f83c8a29e124a6521b76d825b85"}, + {file = "SQLAlchemy-1.4.52-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bdb7b4d889631a3b2a81a3347c4c3f031812eb4adeaa3ee4e6b0d028ad1852b5"}, + {file = "SQLAlchemy-1.4.52-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c294ae4e6bbd060dd79e2bd5bba8b6274d08ffd65b58d106394cb6abbf35cf45"}, + {file = "SQLAlchemy-1.4.52-cp38-cp38-win32.whl", hash = "sha256:bcdfb4b47fe04967669874fb1ce782a006756fdbebe7263f6a000e1db969120e"}, + {file = "SQLAlchemy-1.4.52-cp38-cp38-win_amd64.whl", hash = "sha256:7d0dbc56cb6af5088f3658982d3d8c1d6a82691f31f7b0da682c7b98fa914e91"}, + {file = "SQLAlchemy-1.4.52-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:a551d5f3dc63f096ed41775ceec72fdf91462bb95abdc179010dc95a93957800"}, + {file = "SQLAlchemy-1.4.52-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab773f9ad848118df7a9bbabca53e3f1002387cdbb6ee81693db808b82aaab0"}, + {file = "SQLAlchemy-1.4.52-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2de46f5d5396d5331127cfa71f837cca945f9a2b04f7cb5a01949cf676db7d1"}, + {file = "SQLAlchemy-1.4.52-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7027be7930a90d18a386b25ee8af30514c61f3852c7268899f23fdfbd3107181"}, + {file = "SQLAlchemy-1.4.52-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99224d621affbb3c1a4f72b631f8393045f4ce647dd3262f12fe3576918f8bf3"}, + {file = "SQLAlchemy-1.4.52-cp39-cp39-win32.whl", hash = "sha256:c124912fd4e1bb9d1e7dc193ed482a9f812769cb1e69363ab68e01801e859821"}, + {file = "SQLAlchemy-1.4.52-cp39-cp39-win_amd64.whl", hash = "sha256:2c286fab42e49db23c46ab02479f328b8bdb837d3e281cae546cc4085c83b680"}, + {file = "SQLAlchemy-1.4.52.tar.gz", hash = "sha256:80e63bbdc5217dad3485059bdf6f65a7d43f33c8bde619df5c220edf03d87296"}, ] [package.dependencies] greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} [package.extras] -aiomysql = ["aiomysql", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] asyncio = ["greenlet (!=0.4.17)"] asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"] mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"] @@ -2907,24 +2999,24 @@ mssql-pyodbc = ["pyodbc"] mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] mysql-connector = ["mysql-connector-python"] -oracle = ["cx-oracle (>=7)", "cx-oracle (>=7,<8)"] +oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] postgresql = ["psycopg2 (>=2.7)"] postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql", "pymysql (<1)"] -sqlcipher = ["sqlcipher3-binary"] +sqlcipher = ["sqlcipher3_binary"] [[package]] name = "stack-data" -version = "0.6.2" +version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" files = [ - {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, - {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, ] [package.dependencies] @@ -2937,13 +3029,13 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "tinycss2" -version = "1.2.1" +version = "1.3.0" description = "A tiny CSS parser" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, - {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, + {file = "tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7"}, + {file = "tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d"}, ] [package.dependencies] @@ -2951,7 +3043,7 @@ webencodings = ">=0.4" [package.extras] doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "pytest"] +test = ["pytest", "ruff"] [[package]] name = "tomli" @@ -2966,107 +3058,118 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.1" +version = "0.12.5" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, - {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, ] [[package]] name = "tornado" -version = "6.3.3" +version = "6.4.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, - {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, - {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, - {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, ] [[package]] name = "traitlets" -version = "5.9.0" +version = "5.14.3" description = "Traitlets Python configuration system" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, - {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = true +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, ] [[package]] name = "urllib3" -version = "2.0.7" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, - {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.23.0" +version = "20.26.3" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"}, - {file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"}, + {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, + {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<4" +platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "wcwidth" -version = "0.2.6" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, ] [[package]] @@ -3082,112 +3185,35 @@ files = [ [[package]] name = "wmctrl" -version = "0.4" +version = "0.5" description = "A tool to programmatically control windows inside X" optional = false -python-versions = "*" +python-versions = ">=2.7" files = [ - {file = "wmctrl-0.4.tar.gz", hash = "sha256:66cbff72b0ca06a22ec3883ac3a4d7c41078bdae4fb7310f52951769b10e14e0"}, -] - -[[package]] -name = "wrapt" -version = "1.15.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, - {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, - {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, - {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, - {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, - {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, - {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, - {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, - {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, - {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, - {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, - {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, - {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, - {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, - {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, - {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, - {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, - {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, - {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, + {file = "wmctrl-0.5-py2.py3-none-any.whl", hash = "sha256:ae695c1863a314c899e7cf113f07c0da02a394b968c4772e1936219d9234ddd7"}, + {file = "wmctrl-0.5.tar.gz", hash = "sha256:7839a36b6fe9e2d6fd22304e5dc372dbced2116ba41283ea938b2da57f53e962"}, ] +[package.dependencies] +attrs = "*" + +[package.extras] +test = ["pytest"] + [[package]] name = "zipp" -version = "3.16.2" +version = "3.19.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, - {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, + {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, + {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] box = ["click", "rich"] @@ -3195,5 +3221,5 @@ mark = ["banana-hep", "matplotlib", "pandas", "sqlalchemy"] [metadata] lock-version = "2.0" -python-versions = "^3.8,<3.12" -content-hash = "c47f4aa70036a1a754fc2528a335539342d0919a66dfe1051fe63cbce01338a2" +python-versions = "^3.9,<3.13" +content-hash = "075575a682ab1f660b2dd3c0fc20b9c1a43ebb6e50d5d3a5d786a865810718fe" diff --git a/pyproject.toml b/pyproject.toml index d02ee9f80..89ef66c71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,16 +37,16 @@ packages = [ ] [tool.poetry.dependencies] -python = "^3.8,<3.12" +python = "^3.9,<3.13" numpy = "^1.24" scipy = "^1.10.1" PyYAML = "^6.0" lz4 = "^4.0.2" -numba = "^0.57.0" +numba = "^0.59.0" # ekomark banana-hep = { version = "^0.6.12", optional = true } sqlalchemy = { version = "^1.4.21", optional = true } -pandas = { version = "^1.3.0", optional = true } +pandas = { version = "^2.1.4", optional = true } matplotlib = { version = "^3.5.1", optional = true } rich = { version = "^12.6.0", optional = true } click = { version = ">=8.0.3,<9.0.0", optional = true } @@ -55,7 +55,7 @@ click = { version = ">=8.0.3,<9.0.0", optional = true } optional = true [tool.poetry.group.docs.dependencies] -Sphinx = "^4.3.2" +Sphinx = "^7.0.0" sphinx-rtd-theme = "^1.0.0" sphinxcontrib-bibtex = "^2.4.1" nbsphinx = "^0.8.8" @@ -68,7 +68,7 @@ optional = true pytest = "^7.1.3" pytest-cov = "4.0.0" pytest-env = "^0.6.2" -pylint = "^2.12.2" +pylint = "^3.1.0" [tool.poetry.group.dev.dependencies] pdbpp = "^0.10.3" @@ -78,6 +78,10 @@ asv = "^0.4.2" virtualenv = "^20.13.2" devtools = "^0.10.0" + +[tool.poetry.group.version.dependencies] +tomlkit = "^0.12.5" + [tool.poetry.extras] mark = ["banana-hep", "sqlalchemy", "pandas", "matplotlib"] box = ["rich", "click"] @@ -124,6 +128,16 @@ asv-publish = "asv publish --config benchmarks/asv.conf.json" asv-show = "asv show --config benchmarks/asv.conf.json" asv-clean = { "shell" = "rm -rf benchmarks/env benchmarks/html benchmarks/results" } asv = ["asv-run", "asv-publish", "asv-preview"] +bump-version = { "shell" = "python crates/bump-versions.py $(git describe --tags)" } +compile = "pip install -e crates/eko/" +rdocs.cmd = "cargo doc --workspace --no-deps" +rdocs.env = { RUSTDOCFLAGS = "--html-in-header crates/katex-header.html" } +rdocs-view = "xdg-open target/doc/ekors/index.html" +rdocs-clean = "rm -rf target/doc/" +rtest = "cargo test --workspace" +fmtcheck = "cargo fmt --all -- --check" +clippy = "cargo clippy --no-deps" +rbib = { "shell" = "python crates/make_bib.py > crates/ekore/src/bib.rs" } [tool.pytest.ini_options] testpaths = ['tests/', 'benchmarks/'] diff --git a/pyproject.toml.patch b/pyproject.toml.patch index 65b5daa2c..f4ccc7a37 100644 --- a/pyproject.toml.patch +++ b/pyproject.toml.patch @@ -1,5 +1,5 @@ diff --git a/pyproject.toml b/pyproject.toml -index 31be6cb0..b4ec7c95 100644 +index 088cab32..0d486637 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,20 @@ @@ -11,7 +11,7 @@ index 31be6cb0..b4ec7c95 100644 + +[project] +name = "eko" -+requires-python = ">=3.8" ++requires-python = ">=3.9" +classifiers = [ + "Programming Language :: Rust", + "Programming Language :: Python :: Implementation :: CPython", @@ -25,15 +25,3 @@ index 31be6cb0..b4ec7c95 100644 [tool.poetry] name = "eko" -@@ -124,6 +138,11 @@ asv-publish = "asv publish --config benchmarks/asv.conf.json" - asv-show = "asv show --config benchmarks/asv.conf.json" - asv-clean = { "shell" = "rm -rf benchmarks/env benchmarks/html benchmarks/results" } - asv = ["asv-run", "asv-publish", "asv-preview"] -+compile = "pip install -e crates/eko/" -+rdocs = "cargo doc --workspace --manifest-path crates/Cargo.toml --no-deps" -+rdocs-view = "xdg-open crates/target/doc/ekors/index.html" -+rdocs-clean = "rm -rf crates/target/doc/" -+rtest = "cargo test --workspace --manifest-path crates/Cargo.toml" - - [tool.pytest.ini_options] - testpaths = ['tests/', 'benchmarks/'] diff --git a/rustify.sh b/rustify.sh index 05078d0b7..297afdb3d 100755 --- a/rustify.sh +++ b/rustify.sh @@ -1,5 +1,9 @@ -#!/usr/bin/bash +#!/usr/bin/env bash +# git diff --merge-base master pyproject.toml > pyproject.toml.patch patch -p1 src/eko/evolution_operator/__init__.py.patch patch -p1 `. """ + import logging -from typing import Iterable, List +from typing import Dict, Iterable, List, Tuple import numba as nb import numpy as np +import numpy.typing as npt import scipy from . import constants, matchings @@ -382,6 +384,10 @@ def couplings_expanded_fixed_alphaem(order, couplings_ref, nf, scale_from, scale return np.array([res_as, aem]) +_CouplingsCacheKey = Tuple[float, float, int, float, float] +"""Cache key containing (a0, a1, nf, scale_from, scale_to).""" + + class Couplings: r"""Compute the strong and electromagnetic coupling constants :math:`a_s, a_{em}`. @@ -435,7 +441,7 @@ def assert_positive(name, var): assert_positive("alpha_s_ref", couplings.alphas) assert_positive("alpha_em_ref", couplings.alphaem) - assert_positive("scale_ref", couplings.scale) + assert_positive("scale_ref", couplings.ref[0]) if order[0] not in [1, 2, 3, 4]: raise NotImplementedError( "QCD order has to be an integer between 1 (LO) and 4 (N3LO)" @@ -449,7 +455,7 @@ def assert_positive(name, var): raise ValueError(f"Unknown method {method.value}") self.method = method.value - nf_ref = couplings.num_flavs_ref + nf_ref = couplings.ref[1] scheme_name = hqm_scheme.name self.alphaem_running = couplings.em_running self.decoupled_running = False @@ -458,7 +464,7 @@ def assert_positive(name, var): self.a_ref = np.array(couplings.values) / 4.0 / np.pi # convert to a_s and a_em matching_scales = (np.array(masses) * np.array(thresholds_ratios)).tolist() self.thresholds_ratios = list(thresholds_ratios) - self.atlas = matchings.Atlas(matching_scales, (couplings.scale**2, nf_ref)) + self.atlas = matchings.Atlas(matching_scales, (couplings.ref[0] ** 2, nf_ref)) self.hqm_scheme = scheme_name logger.info( "Strong Coupling: a_s(µ_R^2=%f)%s=%f=%f/(4π)", @@ -479,7 +485,7 @@ def assert_positive(name, var): self.decoupled_running, ) # cache - self.cache = {} + self.cache: Dict[_CouplingsCacheKey, npt.NDArray] = {} @property def mu2_ref(self): diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index f334b83e3..fe07ade9e 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -8,6 +8,7 @@ import os import time from multiprocessing import Pool +from typing import Dict, Tuple import numba as nb import numpy as np @@ -20,11 +21,12 @@ from .. import basis_rotation as br from .. import interpolation, mellin from .. import scale_variations as sv +from ..io.types import EvolutionMethod, OperatorLabel +from ..kernels import ev_method from ..kernels import non_singlet as ns from ..kernels import non_singlet_qed as qed_ns from ..kernels import singlet as s from ..kernels import singlet_qed as qed_s -from ..kernels import utils from ..kernels import valence_qed as qed_v from ..matchings import Segment, lepton_number from ..member import OpMember @@ -601,7 +603,11 @@ def quad_ker_qed( return ker -class Operator(sv.ModeMixin): +OpMembers = Dict[OperatorLabel, OpMember] +"""Map of all operators.""" + + +class Operator(sv.ScaleVariationModeMixin): """Internal representation of a single EKO. The actual matrices are computed upon calling :meth:`compute`. @@ -626,8 +632,8 @@ class Operator(sv.ModeMixin): log_label = "Evolution" # complete list of possible evolution operators labels - full_labels = br.full_labels - full_labels_qed = br.full_unified_labels + full_labels: Tuple[OperatorLabel, ...] = br.full_labels + full_labels_qed: Tuple[OperatorLabel, ...] = br.full_unified_labels def __init__( self, config, managers, segment: Segment, mellin_cut=5e-2, is_threshold=False @@ -640,9 +646,9 @@ def __init__( # TODO make 'cut' external parameter? self._mellin_cut = mellin_cut self.is_threshold = is_threshold - self.op_members = {} + self.op_members: OpMembers = {} self.order = tuple(config["order"]) - self.alphaem_running = self.managers["couplings"].alphaem_running + self.alphaem_running = self.managers.couplings.alphaem_running if self.log_label == "Evolution": self.a = self.compute_a() self.as_list, self.a_half_list = self.compute_aem_list() @@ -664,7 +670,7 @@ def xif2(self): @property def int_disp(self): """Return the interpolation dispatcher.""" - return self.managers["interpol_dispatcher"] + return self.managers.interpolator @property def grid_size(self): @@ -687,7 +693,7 @@ def mu2(self): def compute_a(self): """Return the computed values for :math:`a_s` and :math:`a_{em}`.""" - coupling = self.managers["couplings"] + coupling = self.managers.couplings a0 = coupling.a( self.mu2[0], nf_to=self.nf, @@ -723,8 +729,8 @@ def compute_aem_list(self): as_list = np.array([self.a_s[0], self.a_s[1]]) a_half = np.zeros((ev_op_iterations, 2)) else: - couplings = self.managers["couplings"] - mu2_steps = utils.geomspace(self.q2_from, self.q2_to, 1 + ev_op_iterations) + couplings = self.managers.couplings + mu2_steps = np.geomspace(self.q2_from, self.q2_to, 1 + ev_op_iterations) mu2_l = mu2_steps[0] as_list = np.array( [couplings.a_s(scale_to=mu2, nf_to=self.nf) for mu2 in mu2_steps] @@ -781,6 +787,11 @@ def labels(self): labels.extend(br.singlet_unified_labels) return labels + @property + def ev_method(self): + """Return the evolution method.""" + return ev_method(EvolutionMethod(self.config["method"])) + def quad_ker(self, label, logx, areas): """Return partially initialized integrand function. @@ -804,7 +815,7 @@ def quad_ker(self, label, logx, areas): order=self.order, mode0=label[0], mode1=label[1], - method=self.config["method"], + method=self.ev_method, is_log=self.int_disp.log, logx=logx, areas=areas, @@ -990,27 +1001,23 @@ def copy_ns_ops(self): if self.order[1] == 0: if self.order[0] == 1: # in LO +=-=v for label in ["nsV", "ns-"]: - self.op_members[ - (br.non_singlet_pids_map[label], 0) - ].value = self.op_members[ - (br.non_singlet_pids_map["ns+"], 0) - ].value.copy() - self.op_members[ - (br.non_singlet_pids_map[label], 0) - ].error = self.op_members[ - (br.non_singlet_pids_map["ns+"], 0) - ].error.copy() + self.op_members[(br.non_singlet_pids_map[label], 0)].value = ( + self.op_members[ + (br.non_singlet_pids_map["ns+"], 0) + ].value.copy() + ) + self.op_members[(br.non_singlet_pids_map[label], 0)].error = ( + self.op_members[ + (br.non_singlet_pids_map["ns+"], 0) + ].error.copy() + ) elif self.order[0] == 2: # in NLO -=v - self.op_members[ - (br.non_singlet_pids_map["nsV"], 0) - ].value = self.op_members[ - (br.non_singlet_pids_map["ns-"], 0) - ].value.copy() - self.op_members[ - (br.non_singlet_pids_map["nsV"], 0) - ].error = self.op_members[ - (br.non_singlet_pids_map["ns-"], 0) - ].error.copy() + self.op_members[(br.non_singlet_pids_map["nsV"], 0)].value = ( + self.op_members[(br.non_singlet_pids_map["ns-"], 0)].value.copy() + ) + self.op_members[(br.non_singlet_pids_map["nsV"], 0)].error = ( + self.op_members[(br.non_singlet_pids_map["ns-"], 0)].error.copy() + ) # at O(as0aem1) u-=u+, d-=d+ # starting from O(as1aem1) P+ != P- # However the solution with pure QED is not implemented in EKO diff --git a/src/eko/evolution_operator/__init__.py.patch b/src/eko/evolution_operator/__init__.py.patch index 00f8815d3..995d77b6b 100644 --- a/src/eko/evolution_operator/__init__.py.patch +++ b/src/eko/evolution_operator/__init__.py.patch @@ -1,8 +1,8 @@ diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py -index 29e67c19..08e768e3 100644 +index fe07ade9..0f58c9e5 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py -@@ -3,15 +3,15 @@ r"""Contains the central operator classes. +@@ -3,16 +3,16 @@ r"""Contains the central operator classes. See :doc:`Operator overview `. """ @@ -11,6 +11,7 @@ index 29e67c19..08e768e3 100644 import os import time from multiprocessing import Pool + from typing import Dict, Tuple +import ekors import numba as nb @@ -20,9 +21,9 @@ index 29e67c19..08e768e3 100644 import ekore.anomalous_dimensions.polarized.space_like as ad_ps import ekore.anomalous_dimensions.unpolarized.space_like as ad_us -@@ -28,92 +28,10 @@ from ..kernels import utils +@@ -30,92 +30,10 @@ from ..kernels import singlet_qed as qed_s from ..kernels import valence_qed as qed_v - from ..matchings import Segment + from ..matchings import Segment, lepton_number from ..member import OpMember +from .quad_ker import cb_quad_ker_qcd @@ -114,7 +115,7 @@ index 29e67c19..08e768e3 100644 spec = [ ("is_singlet", nb.boolean), ("is_QEDsinglet", nb.boolean), -@@ -185,403 +103,6 @@ class QuadKerBase: +@@ -187,421 +105,6 @@ class QuadKerBase: return self.path.prefactor * pj * self.path.jac @@ -142,6 +143,7 @@ index 29e67c19..08e768e3 100644 - n3lo_ad_variation, - is_polarized, - is_time_like, +- use_fhmruvv, -): - """Raw evolution kernel inside quad. - @@ -188,11 +190,13 @@ index 29e67c19..08e768e3 100644 - is_threshold : boolean - is this an intermediate threshold operator? - n3lo_ad_variation : tuple -- |N3LO| anomalous dimension variation ``(gg_var, gq_var, qg_var, qq_var)`` +- |N3LO| anomalous dimension variation ``(gg, gq, qg, qq, nsp, nsm, nsv)`` - is_polarized : boolean - is polarized evolution ? - is_time_like : boolean - is time-like evolution ? +- use_fhmruvv : bool +- if True use the |FHMRUVV| |N3LO| anomalous dimension - - Returns - ------- @@ -221,6 +225,7 @@ index 29e67c19..08e768e3 100644 - is_polarized, - is_time_like, - n3lo_ad_variation, +- use_fhmruvv, - ) - else: - ker = quad_ker_qed( @@ -241,6 +246,7 @@ index 29e67c19..08e768e3 100644 - sv_mode, - is_threshold, - n3lo_ad_variation, +- use_fhmruvv, - ) - - # recombine everything @@ -265,6 +271,7 @@ index 29e67c19..08e768e3 100644 - is_polarized, - is_time_like, - n3lo_ad_variation, +- use_fhmruvv, -): - """Raw evolution kernel inside quad. - @@ -297,7 +304,9 @@ index 29e67c19..08e768e3 100644 - is_threshold : boolean - is this an itermediate threshold operator? - n3lo_ad_variation : tuple -- |N3LO| anomalous dimension variation ``(gg_var, gq_var, qg_var, qq_var)`` +- |N3LO| anomalous dimension variation ``(gg, gq, qg, qq, nsp, nsm, nsv)`` +- use_fhmruvv : bool +- if True use the |FHMRUVV| |N3LO| anomalous dimensions - - Returns - ------- @@ -316,7 +325,7 @@ index 29e67c19..08e768e3 100644 - gamma_singlet = ad_ut.gamma_singlet(order, ker_base.n, nf) - else: - gamma_singlet = ad_us.gamma_singlet( -- order, ker_base.n, nf, n3lo_ad_variation +- order, ker_base.n, nf, n3lo_ad_variation, use_fhmruvv - ) - # scale var exponentiated is directly applied on gamma - if sv_mode == sv.Modes.exponentiated: @@ -349,7 +358,9 @@ index 29e67c19..08e768e3 100644 - if is_time_like: - gamma_ns = ad_ut.gamma_ns(order, mode0, ker_base.n, nf) - else: -- gamma_ns = ad_us.gamma_ns(order, mode0, ker_base.n, nf) +- gamma_ns = ad_us.gamma_ns( +- order, mode0, ker_base.n, nf, n3lo_ad_variation, use_fhmruvv +- ) - if sv_mode == sv.Modes.exponentiated: - gamma_ns = sv.exponentiated.gamma_variation(gamma_ns, order, nf, L) - ker = ns.dispatcher( @@ -385,6 +396,7 @@ index 29e67c19..08e768e3 100644 - sv_mode, - is_threshold, - n3lo_ad_variation, +- use_fhmruvv, -): - """Raw evolution kernel inside quad. - @@ -425,7 +437,9 @@ index 29e67c19..08e768e3 100644 - is_threshold : boolean - is this an itermediate threshold operator? - n3lo_ad_variation : tuple -- |N3LO| anomalous dimension variation ``(gg_var, gq_var, qg_var, qq_var)`` +- |N3LO| anomalous dimension variation ``(gg, gq, qg, qq, nsp, nsm, nsv)`` +- use_fhmruvv : bool +- if True use the |FHMRUVV| |N3LO| anomalous dimensions - - Returns - ------- @@ -434,11 +448,13 @@ index 29e67c19..08e768e3 100644 - """ - # compute the actual evolution kernel for QEDxQCD - if ker_base.is_QEDsinglet: -- gamma_s = ad_us.gamma_singlet_qed(order, ker_base.n, nf, n3lo_ad_variation) +- gamma_s = ad_us.gamma_singlet_qed( +- order, ker_base.n, nf, n3lo_ad_variation, use_fhmruvv +- ) - # scale var exponentiated is directly applied on gamma - if sv_mode == sv.Modes.exponentiated: - gamma_s = sv.exponentiated.gamma_variation_qed( -- gamma_s, order, nf, L, alphaem_running +- gamma_s, order, nf, lepton_number(mu2_to), L, alphaem_running - ) - ker = qed_s.dispatcher( - order, @@ -462,11 +478,13 @@ index 29e67c19..08e768e3 100644 - ) @ np.ascontiguousarray(ker) - ker = select_QEDsinglet_element(ker, mode0, mode1) - elif ker_base.is_QEDvalence: -- gamma_v = ad_us.gamma_valence_qed(order, ker_base.n, nf) +- gamma_v = ad_us.gamma_valence_qed( +- order, ker_base.n, nf, n3lo_ad_variation, use_fhmruvv +- ) - # scale var exponentiated is directly applied on gamma - if sv_mode == sv.Modes.exponentiated: - gamma_v = sv.exponentiated.gamma_variation_qed( -- gamma_v, order, nf, L, alphaem_running +- gamma_v, order, nf, lepton_number(mu2_to), L, alphaem_running - ) - ker = qed_v.dispatcher( - order, @@ -487,11 +505,13 @@ index 29e67c19..08e768e3 100644 - ) @ np.ascontiguousarray(ker) - ker = select_QEDvalence_element(ker, mode0, mode1) - else: -- gamma_ns = ad_us.gamma_ns_qed(order, mode0, ker_base.n, nf) +- gamma_ns = ad_us.gamma_ns_qed( +- order, mode0, ker_base.n, nf, n3lo_ad_variation, use_fhmruvv +- ) - # scale var exponentiated is directly applied on gamma - if sv_mode == sv.Modes.exponentiated: - gamma_ns = sv.exponentiated.gamma_variation_qed( -- gamma_ns, order, nf, L, alphaem_running +- gamma_ns, order, nf, lepton_number(mu2_to), L, alphaem_running - ) - ker = qed_ns.dispatcher( - order, @@ -514,13 +534,12 @@ index 29e67c19..08e768e3 100644 - ) - return ker - -- - class Operator(sv.ModeMixin): - """Internal representation of a single EKO. -@@ -784,49 +305,6 @@ class Operator(sv.ModeMixin): - labels.extend(br.singlet_unified_labels) - return labels + OpMembers = Dict[OperatorLabel, OpMember] + """Map of all operators.""" +@@ -792,50 +295,6 @@ class Operator(sv.ScaleVariationModeMixin): + """Return the evolution method.""" + return ev_method(EvolutionMethod(self.config["method"])) - def quad_ker(self, label, logx, areas): - """Return partially initialized integrand function. @@ -545,7 +564,7 @@ index 29e67c19..08e768e3 100644 - order=self.order, - mode0=label[0], - mode1=label[1], -- method=self.config["method"], +- method=self.ev_method, - is_log=self.int_disp.log, - logx=logx, - areas=areas, @@ -563,12 +582,13 @@ index 29e67c19..08e768e3 100644 - n3lo_ad_variation=self.config["n3lo_ad_variation"], - is_polarized=self.config["polarized"], - is_time_like=self.config["time_like"], +- use_fhmruvv=self.config["use_fhmruvv"], - ) - def initialize_op_members(self): """Init all operators with the identity or zeros.""" eye = OpMember( -@@ -849,10 +327,7 @@ class Operator(sv.ModeMixin): +@@ -858,10 +317,7 @@ class Operator(sv.ScaleVariationModeMixin): else: self.op_members[n] = zero.copy() @@ -580,7 +600,7 @@ index 29e67c19..08e768e3 100644 """Run the integration for each grid point. Parameters -@@ -867,18 +342,56 @@ class Operator(sv.ModeMixin): +@@ -876,18 +332,56 @@ class Operator(sv.ScaleVariationModeMixin): """ column = [] k, logx = log_grid diff --git a/src/eko/evolution_operator/flavors.py b/src/eko/evolution_operator/flavors.py index fac94a608..087294744 100644 --- a/src/eko/evolution_operator/flavors.py +++ b/src/eko/evolution_operator/flavors.py @@ -246,6 +246,7 @@ def qed_rotation_parameters(nf): nd_h = nf - nu_h a = (nd_h / nu_h * nu_l - nd_l) / (nf - 1) b = nf / nu_h * nu_l / (nf - 1) + c, d, e, f = (np.nan,) * 4 if nf in [4, 6]: # heavy flavor is up-like c = nd_h / nu_h d = nu_l / (nf - 1) diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index d1ddb23bc..969750389 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -4,9 +4,10 @@ previously instantiated information and does the actual computation of the Q2s. """ + import logging -from dataclasses import astuple -from typing import Dict, List, Optional +from dataclasses import dataclass +from typing import Any, Dict, List, Optional import numpy as np import numpy.typing as npt @@ -17,9 +18,9 @@ from ..interpolation import InterpolatorDispatcher from ..io.runcards import Configs, Debug from ..io.types import EvolutionPoint as EPoint -from ..io.types import Order +from ..io.types import Order, SquaredScale from ..matchings import Atlas, Segment, flavor_shift, is_downward_path -from . import Operator, flavors, matching_condition, physical +from . import Operator, OpMembers, flavors, matching_condition, physical from .operator_matrix_element import OperatorMatrixElement logger = logging.getLogger(__name__) @@ -28,7 +29,16 @@ """In particular, only the ``operator`` and ``error`` fields are expected.""" -class OperatorGrid(sv.ModeMixin): +@dataclass(frozen=True) +class Managers: + """Set of steering objects.""" + + atlas: Atlas + couplings: Couplings + interpolator: InterpolatorDispatcher + + +class OperatorGrid(sv.ScaleVariationModeMixin): """Collection of evolution operators for several scales. The operator grid is the driver class of the evolution. @@ -51,7 +61,6 @@ def __init__( masses: List[float], mass_scheme, thresholds_ratios: List[float], - intrinsic_flavors: list, xif: float, n3lo_ad_variation: tuple, matching_order: Order, @@ -63,9 +72,8 @@ def __init__( use_fhmruvv: bool, ): # check - config = {} + config: Dict[str, Any] = {} config["order"] = order - config["intrinsic_range"] = intrinsic_flavors config["xif2"] = xif**2 config["HQ"] = mass_scheme config["ModSV"] = configs.scvar_method @@ -94,13 +102,13 @@ def __init__( self.config = config self.q2_grid = mu2grid - self.managers = dict( - thresholds_config=atlas, + self.managers = Managers( + atlas=atlas, couplings=couplings, - interpol_dispatcher=interpol_dispatcher, + interpolator=interpol_dispatcher, ) - self._threshold_operators = {} - self._matching_operators = {} + self._threshold_operators: Dict[Segment, Operator] = {} + self._matching_operators: Dict[SquaredScale, OpMembers] = {} def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: """Generate the threshold operators. @@ -122,7 +130,6 @@ def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: is_downward = is_downward_path(path) shift = flavor_shift(is_downward) for seg in path[:-1]: - new_op_key = astuple(seg) kthr = self.config["thresholds_ratios"][seg.nf - shift] ome = OperatorMatrixElement( self.config, @@ -133,13 +140,13 @@ def get_threshold_operators(self, path: List[Segment]) -> List[Operator]: np.log(kthr), self.config["HQ"] == "MSBAR", ) - if new_op_key not in self._threshold_operators: + if seg not in self._threshold_operators: # Compute the operator and store it logger.info("Prepare threshold operator") op_th = Operator(self.config, self.managers, seg, is_threshold=True) op_th.compute() - self._threshold_operators[new_op_key] = op_th - thr_ops.append(self._threshold_operators[new_op_key]) + self._threshold_operators[seg] = op_th + thr_ops.append(self._threshold_operators[seg]) # Compute the matching conditions and store it if seg.target not in self._matching_operators: @@ -158,7 +165,7 @@ def generate(self, q2: EPoint) -> OpDict: """ # The lists of areas as produced by the thresholds - path = self.managers["thresholds_config"].path(q2) + path = self.managers.atlas.path(q2) # Prepare the path for the composition of the operator thr_ops = self.get_threshold_operators(path) # we start composing with the highest operator ... @@ -166,16 +173,15 @@ def generate(self, q2: EPoint) -> OpDict: operator.compute() is_downward = is_downward_path(path) - intrinsic_range = [4, 5, 6] if is_downward else self.config["intrinsic_range"] qed = self.config["order"][1] > 0 final_op = physical.PhysicalOperator.ad_to_evol_map( - operator.op_members, operator.nf, operator.q2_to, intrinsic_range, qed + operator.op_members, operator.nf, operator.q2_to, qed ) # and multiply the lower ones from the right for op in reversed(list(thr_ops)): phys_op = physical.PhysicalOperator.ad_to_evol_map( - op.op_members, op.nf, op.q2_to, intrinsic_range, qed + op.op_members, op.nf, op.q2_to, qed ) # join with the basis rotation, since matching requires c+ (or likewise) @@ -184,7 +190,6 @@ def generate(self, q2: EPoint) -> OpDict: self._matching_operators[op.q2_to], nf_match, op.q2_to, - intrinsic_range=intrinsic_range, qed=qed, ) if is_downward: diff --git a/src/eko/evolution_operator/matching_condition.py b/src/eko/evolution_operator/matching_condition.py index 8df4775ff..e84ef4d2e 100644 --- a/src/eko/evolution_operator/matching_condition.py +++ b/src/eko/evolution_operator/matching_condition.py @@ -20,8 +20,7 @@ def split_ad_to_evol_map( op_members, nf, q2_thr, - intrinsic_range, - qed, + qed=False, ): """ Create the instance from the |OME|. @@ -35,8 +34,6 @@ def split_ad_to_evol_map( number of active flavors *below* the threshold q2_thr: float threshold value - intrinsic_range : list - list of intrinsic quark pids qed : bool activate qed """ @@ -78,27 +75,26 @@ def split_ad_to_evol_map( ) # intrinsic matching - if len(intrinsic_range) != 0: - op_id = member.OpMember.id_like(op_members[(200, 200)]) - for intr_fl in intrinsic_range: - ihq = br.quark_names[intr_fl - 1] # find name - if intr_fl > nf + 1: - # keep the higher quarks as they are - m[f"{ihq}+.{ihq}+"] = op_id.copy() - m[f"{ihq}-.{ihq}-"] = op_id.copy() - elif intr_fl == nf + 1: - # match the missing contribution from h+ and h- - m.update( - { - f"{ihq}+.{ihq}+": op_members[ - (br.matching_hplus_pid, br.matching_hplus_pid) - ], - f"S.{ihq}+": op_members[(100, br.matching_hplus_pid)], - f"g.{ihq}+": op_members[(21, br.matching_hplus_pid)], - f"{ihq}-.{ihq}-": op_members[ - (br.matching_hminus_pid, br.matching_hminus_pid) - ], - # f"V.{ihq}-": op_members[(200, br.matching_hminus_pid)], - } - ) + op_id = member.OpMember.id_like(op_members[(200, 200)]) + for intr_fl in [4, 5, 6]: + ihq = br.quark_names[intr_fl - 1] # find name + if intr_fl > nf + 1: + # keep the higher quarks as they are + m[f"{ihq}+.{ihq}+"] = op_id.copy() + m[f"{ihq}-.{ihq}-"] = op_id.copy() + elif intr_fl == nf + 1: + # match the missing contribution from h+ and h- + m.update( + { + f"{ihq}+.{ihq}+": op_members[ + (br.matching_hplus_pid, br.matching_hplus_pid) + ], + f"S.{ihq}+": op_members[(100, br.matching_hplus_pid)], + f"g.{ihq}+": op_members[(21, br.matching_hplus_pid)], + f"{ihq}-.{ihq}-": op_members[ + (br.matching_hminus_pid, br.matching_hminus_pid) + ], + # f"V.{ihq}-": op_members[(200, br.matching_hminus_pid)], + } + ) return cls.promote_names(m, q2_thr) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 202fd18d9..022f80730 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -1,6 +1,7 @@ """The |OME| for the non-trivial matching conditions in the |VFNS| evolution.""" import copy +import enum import functools import logging @@ -20,6 +21,33 @@ logger = logging.getLogger(__name__) +class MatchingMethods(enum.IntEnum): + """Enumerate matching methods.""" + + FORWARD = enum.auto() + BACKWARD_EXACT = enum.auto() + BACKWARD_EXPANDED = enum.auto() + + +def matching_method(s: InversionMethod) -> MatchingMethods: + """Return the matching method. + + Parameters + ---------- + s : + string representation + + Returns + ------- + i : + int representation + + """ + if s is not None: + return MatchingMethods["BACKWARD_" + s.value.upper()] + return MatchingMethods.FORWARD + + @nb.njit(cache=True) def build_ome(A, matching_order, a_s, backward_method): r"""Construct the matching expansion in :math:`a_s` with the appropriate method. @@ -32,7 +60,7 @@ def build_ome(A, matching_order, a_s, backward_method): perturbation matching order a_s : float strong coupling, needed only for the exact inverse - backward_method : InversionMethod or None + backward_method : MatchingMethods empty or method for inverting the matching condition (exact or expanded) Returns @@ -51,7 +79,7 @@ def build_ome(A, matching_order, a_s, backward_method): ome = np.eye(len(A[0]), dtype=np.complex_) A = A[:, :, :] A = np.ascontiguousarray(A) - if backward_method is InversionMethod.EXPANDED: + if backward_method is MatchingMethods.BACKWARD_EXPANDED: # expended inverse if matching_order[0] >= 1: ome -= a_s * A[0] @@ -68,7 +96,7 @@ def build_ome(A, matching_order, a_s, backward_method): if matching_order[0] >= 3: ome += a_s**3 * A[2] # need inverse exact ? so add the missing pieces - if backward_method is InversionMethod.EXACT: + if backward_method is MatchingMethods.BACKWARD_EXACT: ome = np.linalg.inv(ome) return ome @@ -199,7 +227,7 @@ class OperatorMatrixElement(Operator): log_label = "Matching" # complete list of possible matching operators labels - full_labels = [ + full_labels = ( *br.singlet_labels, (br.matching_hplus_pid, 21), (br.matching_hplus_pid, 100), @@ -210,17 +238,15 @@ class OperatorMatrixElement(Operator): (200, br.matching_hminus_pid), (br.matching_hminus_pid, 200), (br.matching_hminus_pid, br.matching_hminus_pid), - ] + ) # still valid in QED since Sdelta and Vdelta matchings are diagonal full_labels_qed = copy.deepcopy(full_labels) def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): super().__init__(config, managers, Segment(q2, q2, nf)) - self.backward_method = config["backward_inversion"] if is_backward else None - if is_backward: - self.is_intrinsic = True - else: - self.is_intrinsic = bool(len(config["intrinsic_range"]) != 0) + self.backward_method = matching_method( + config["backward_inversion"] if is_backward else None + ) self.L = L self.is_msbar = is_msbar # Note for the moment only QCD matching is implemented @@ -241,11 +267,10 @@ def labels(self): logger.warning("%s: skipping non-singlet sector", self.log_label) else: labels.append((200, 200)) - if self.is_intrinsic or self.backward_method is not None: - # intrinsic labels, which are not zero at NLO - labels.append((br.matching_hminus_pid, br.matching_hminus_pid)) - # These contributions are always 0 for the moment - # labels.extend([(200, br.matching_hminus_pid), (br.matching_hminus_pid, 200)]) + # intrinsic labels, which are not zero at NLO + labels.append((br.matching_hminus_pid, br.matching_hminus_pid)) + # These contributions are always 0 for the moment + # labels.extend([(200, br.matching_hminus_pid), (br.matching_hminus_pid, 200)]) # same for singlet if self.config["debug_skip_singlet"]: logger.warning("%s: skipping singlet sector", self.log_label) @@ -257,14 +282,13 @@ def labels(self): (br.matching_hplus_pid, 100), ] ) - if self.is_intrinsic or self.backward_method is not None: - labels.extend( - [ - (21, br.matching_hplus_pid), - (100, br.matching_hplus_pid), - (br.matching_hplus_pid, br.matching_hplus_pid), - ] - ) + labels.extend( + [ + (21, br.matching_hplus_pid), + (100, br.matching_hplus_pid), + (br.matching_hplus_pid, br.matching_hplus_pid), + ] + ) return labels def quad_ker(self, label, logx, areas): @@ -309,7 +333,7 @@ def a_s(self): Note that here you need to use :math:`a_s^{n_f+1}` """ - sc = self.managers["couplings"] + sc = self.managers.couplings return sc.a_s( self.q2_from * (self.xif2 if self.sv_mode == sv.Modes.exponentiated else 1.0), @@ -329,7 +353,7 @@ def compute(self): self.log_label, self.order[0], self.order[1], - self.backward_method, + MatchingMethods(self.backward_method).name, ) self.integrate() diff --git a/src/eko/evolution_operator/physical.py b/src/eko/evolution_operator/physical.py index 1ee501a2a..f8a3545d8 100644 --- a/src/eko/evolution_operator/physical.py +++ b/src/eko/evolution_operator/physical.py @@ -1,4 +1,5 @@ """Contains the :class:`PhysicalOperator` class.""" + from .. import basis_rotation as br from .. import member @@ -22,7 +23,7 @@ class PhysicalOperator(member.OperatorBase): """ @classmethod - def ad_to_evol_map(cls, op_members, nf, q2_final, intrinsic_range, qed): + def ad_to_evol_map(cls, op_members, nf, q2_final, qed=False): """ Obtain map between the 3-dimensional anomalous dimension basis and the 4-dimensional evolution basis. @@ -34,8 +35,6 @@ def ad_to_evol_map(cls, op_members, nf, q2_final, intrinsic_range, qed): operator members in anomalous dimension basis nf : int number of active light flavors - intrinsic_range : sequence - intrinsic heavy flavors qed : bool activate qed @@ -93,15 +92,14 @@ def ad_to_evol_map(cls, op_members, nf, q2_final, intrinsic_range, qed): m["Tu8.Tu8"] = op_members[(br.non_singlet_pids_map["ns+u"], 0)] m["Vu8.Vu8"] = op_members[(br.non_singlet_pids_map["ns-u"], 0)] # deal with intrinsic heavy quark PDFs - if intrinsic_range is not None: - hqfl = "cbt" - op_id = member.OpMember.id_like(op_members[(21, 21)]) - for intr_fl in intrinsic_range: - if intr_fl <= nf: # light quarks are not intrinsic - continue - hq = hqfl[intr_fl - 4] # find name - # intrinsic means no evolution, i.e. they are evolving with the identity - m[f"{hq}+.{hq}+"] = op_id.copy() - m[f"{hq}-.{hq}-"] = op_id.copy() + hqfl = "cbt" + op_id = member.OpMember.id_like(op_members[(21, 21)]) + for intr_fl in [4, 5, 6]: + if intr_fl <= nf: # light quarks are not intrinsic + continue + hq = hqfl[intr_fl - 4] # find name + # intrinsic means no evolution, i.e. they are evolving with the identity + m[f"{hq}+.{hq}+"] = op_id.copy() + m[f"{hq}-.{hq}-"] = op_id.copy() # map key to MemberName return cls.promote_names(m, q2_final) diff --git a/src/eko/evolution_operator/quad_ker.py b/src/eko/evolution_operator/quad_ker.py index 9303f8aa9..798cebe6b 100644 --- a/src/eko/evolution_operator/quad_ker.py +++ b/src/eko/evolution_operator/quad_ker.py @@ -11,7 +11,6 @@ from .. import scale_variations as sv from ..kernels import non_singlet as ns from ..kernels import singlet as s -from ..kernels import utils from ..matchings import Segment from ..member import OpMember @@ -69,6 +68,7 @@ def select_singlet_element(ker, mode0, mode1): nb.types.bool_, # is_threshold ), cache=True, + nopython=True, ) def cb_quad_ker_qcd( re_gamma_raw, @@ -104,7 +104,7 @@ def cb_quad_ker_qcd( areas = nb.carray(areas_raw, (areas_x, areas_y)) pj = interpolation.evaluate_grid(n, is_log, logx, areas) # TODO recover parameters - method = "iterate-expanded" + method = "iterate-exact" sv_mode = sv.Modes.exponentiated order = (order_qcd, 0) ev_op_max_order = (ev_op_max_order_qcd, 0) diff --git a/src/eko/gamma.py b/src/eko/gamma.py index b71ce843a..668219a75 100644 --- a/src/eko/gamma.py +++ b/src/eko/gamma.py @@ -2,6 +2,7 @@ See :doc:`pQCD ingredients `. """ + import numba as nb from eko.constants import zeta3, zeta4, zeta5 diff --git a/src/eko/interpolation.py b/src/eko/interpolation.py index 170eb8892..ef03c7fa0 100644 --- a/src/eko/interpolation.py +++ b/src/eko/interpolation.py @@ -4,6 +4,7 @@ Upon construction the dispatcher generates a number of functions to evaluate the interpolator. """ + import logging import math from typing import Sequence, Union diff --git a/src/eko/io/bases.py b/src/eko/io/bases.py deleted file mode 100644 index 97a28dc36..000000000 --- a/src/eko/io/bases.py +++ /dev/null @@ -1,117 +0,0 @@ -"""Operators bases.""" -from dataclasses import dataclass, fields -from typing import Optional - -import numpy as np -import numpy.typing as npt - -from .. import basis_rotation as br -from .. import interpolation -from .dictlike import DictLike - - -@dataclass -class Bases(DictLike): - """Rotations related configurations. - - Here "Rotation" is intended in a broad sense: it includes both rotations in - flavor space (labeled with suffix `pids`) and in :math:`x`-space (labeled - with suffix `grid`). - Rotations in :math:`x`-space correspond to reinterpolate the result on a - different basis of polynomials. - - """ - - xgrid: interpolation.XGrid - """Internal momentum fraction grid.""" - _targetgrid: Optional[interpolation.XGrid] = None - _inputgrid: Optional[interpolation.XGrid] = None - _targetpids: Optional[npt.NDArray] = None - _inputpids: Optional[npt.NDArray] = None - - def __post_init__(self): - """Adjust types when loaded from serialized object.""" - for attr in ("xgrid", "_inputgrid", "_targetgrid"): - value = getattr(self, attr) - if value is None: - continue - if isinstance(value, (np.ndarray, list)): - setattr(self, attr, interpolation.XGrid(value)) - elif not isinstance(value, interpolation.XGrid): - setattr(self, attr, interpolation.XGrid.load(value)) - - @property - def pids(self): - """Internal flavor basis, used for computation.""" - return np.array(br.flavor_basis_pids) - - @property - def inputpids(self) -> npt.NDArray: - """Provide pids expected on the input PDF.""" - if self._inputpids is None: - return self.pids - return self._inputpids - - @inputpids.setter - def inputpids(self, value): - self._inputpids = value - - @property - def targetpids(self) -> npt.NDArray: - """Provide pids corresponding to the output PDF.""" - if self._targetpids is None: - return self.pids - return self._targetpids - - @targetpids.setter - def targetpids(self, value): - self._targetpids = value - - @property - def inputgrid(self) -> interpolation.XGrid: - """Provide :math:`x`-grid expected on the input PDF.""" - if self._inputgrid is None: - return self.xgrid - return self._inputgrid - - @inputgrid.setter - def inputgrid(self, value: interpolation.XGrid): - self._inputgrid = value - - @property - def targetgrid(self) -> interpolation.XGrid: - """Provide :math:`x`-grid corresponding to the output PDF.""" - if self._targetgrid is None: - return self.xgrid - return self._targetgrid - - @targetgrid.setter - def targetgrid(self, value: interpolation.XGrid): - self._targetgrid = value - - @classmethod - def from_dict(cls, dictionary: dict): - """Deserialize rotation. - - Load from full state, but with public names. - - """ - d = dictionary.copy() - for f in fields(cls): - if f.name.startswith("_"): - d[f.name] = d.pop(f.name[1:]) - return cls._from_dict(d) - - @property - def raw(self): - """Serialize rotation. - - Pass through interfaces, access internal values but with a public name. - - """ - d = self._raw() - for key in d.copy(): - if key.startswith("_"): - d[key[1:]] = d.pop(key) - - return d diff --git a/src/eko/io/dictlike.py b/src/eko/io/dictlike.py index 29f947ab2..da60066b3 100644 --- a/src/eko/io/dictlike.py +++ b/src/eko/io/dictlike.py @@ -4,6 +4,7 @@ codified in more native structures. """ + import copy import dataclasses import enum diff --git a/src/eko/io/exceptions.py b/src/eko/io/exceptions.py index b924f8057..13f952bda 100644 --- a/src/eko/io/exceptions.py +++ b/src/eko/io/exceptions.py @@ -1,4 +1,5 @@ """IO generic exceptions.""" + import os diff --git a/src/eko/io/inventory.py b/src/eko/io/inventory.py index efdd2e9b0..9b25ad75d 100644 --- a/src/eko/io/inventory.py +++ b/src/eko/io/inventory.py @@ -1,8 +1,9 @@ """Manage assets used during computation.""" + import base64 from dataclasses import asdict, dataclass, field from pathlib import Path -from typing import Dict, Generic, Optional, Type, TypeVar +from typing import Dict, Generic, Literal, Optional, Type, TypeVar import yaml @@ -10,7 +11,7 @@ from .items import Header, Operator NBYTES = 8 -ENDIANNESS = "little" +ENDIANNESS: Literal["little", "big"] = "little" HEADER_EXT = ".yaml" ARRAY_EXT = [".npy", ".npz"] diff --git a/src/eko/io/items.py b/src/eko/io/items.py index cbc7591e0..8d6d6eb2d 100644 --- a/src/eko/io/items.py +++ b/src/eko/io/items.py @@ -1,4 +1,5 @@ """Inventory items definition.""" + import io from dataclasses import asdict, dataclass from typing import BinaryIO, Optional, Union diff --git a/src/eko/io/legacy.py b/src/eko/io/legacy.py index 1df9941b1..41dc8af85 100644 --- a/src/eko/io/legacy.py +++ b/src/eko/io/legacy.py @@ -1,7 +1,7 @@ """Support legacy storage formats.""" + import dataclasses import io -import os import pathlib import tarfile import tempfile @@ -12,18 +12,26 @@ import numpy as np import yaml -from eko.interpolation import XGrid -from eko.io.runcards import flavored_mugrid -from eko.quantities.heavy_quarks import HeavyInfo, HeavyQuarkMasses, MatchingRatios - +from ..interpolation import XGrid +from ..io.runcards import flavored_mugrid +from ..quantities.heavy_quarks import ( + HeavyInfo, + HeavyQuarkMasses, + MatchingRatios, + QuarkMassScheme, +) from . import raw from .dictlike import DictLike from .struct import EKO, Operator from .types import EvolutionPoint as EPoint -from .types import RawCard +from .types import RawCard, ReferenceRunning + +_MC = 1.51 +_MB = 4.92 +_MT = 172.5 -def load_tar(source: os.PathLike, dest: os.PathLike, errors: bool = False): +def load_tar(source: pathlib.Path, dest: pathlib.Path, errors: bool = False): """Load tar representation from file. Compliant with :meth:`dump_tar` output. @@ -38,8 +46,8 @@ def load_tar(source: os.PathLike, dest: os.PathLike, errors: bool = False): whether to load also errors (default ``False``) """ - with tempfile.TemporaryDirectory() as tmpdir: - tmpdir = pathlib.Path(tmpdir) + with tempfile.TemporaryDirectory() as tmpdirr: + tmpdir = pathlib.Path(tmpdirr) with tarfile.open(source, "r") as tar: raw.safe_extractall(tar, tmpdir) @@ -59,7 +67,7 @@ def load_tar(source: os.PathLike, dest: os.PathLike, errors: bool = False): if op5 is None: op5 = metaold["mu2grid"] grid = op5to4( - flavored_mugrid(op5, theory.heavy.masses, theory.heavy.matching_ratios), arrays + flavored_mugrid(op5, [_MC, _MB, _MT], theory.heavy.matching_ratios), arrays ) with EKO.create(dest) as builder: @@ -91,11 +99,14 @@ class PseudoTheory(DictLike): def from_old(cls, old: RawCard): """Load from old metadata.""" heavy = HeavyInfo( - num_flavs_init=4, - num_flavs_max_pdf=None, - intrinsic_flavors=None, - masses=HeavyQuarkMasses([1.51, 4.92, 172.5]), - masses_scheme=None, + masses=HeavyQuarkMasses( + [ + ReferenceRunning([_MC, np.inf]), + ReferenceRunning([_MB, np.inf]), + ReferenceRunning([_MT, np.inf]), + ] + ), + masses_scheme=QuarkMassScheme.POLE, matching_ratios=MatchingRatios([1.0, 1.0, 1.0]), ) return cls(heavy=heavy) @@ -110,7 +121,7 @@ class PseudoOperator(DictLike): """ - mu20: float + init: EPoint evolgrid: List[EPoint] xgrid: XGrid configs: dict @@ -118,13 +129,13 @@ class PseudoOperator(DictLike): @classmethod def from_old(cls, old: RawCard): """Load from old metadata.""" - mu20 = float(old["q2_ref"]) + mu0 = float(np.sqrt(float(old["q2_ref"]))) mu2list = old.get("Q2grid") if mu2list is None: mu2list = old["mu2grid"] mu2grid = np.array(mu2list) evolgrid = flavored_mugrid( - np.sqrt(mu2grid).tolist(), [1.51, 4.92, 172.5], [1, 1, 1] + np.sqrt(mu2grid).tolist(), [_MC, _MB, _MT], [1, 1, 1] ) xgrid = XGrid(old["interpolation_xgrid"]) @@ -134,7 +145,7 @@ def from_old(cls, old: RawCard): interpolation_is_log=old.get("interpolation_is_log"), ) - return cls(mu20=mu20, evolgrid=evolgrid, xgrid=xgrid, configs=configs) + return cls(init=(mu0, 4), evolgrid=evolgrid, xgrid=xgrid, configs=configs) ARRAY_SUFFIX = ".npy.lz4" diff --git a/src/eko/io/manipulate.py b/src/eko/io/manipulate.py index e9cc89538..362c8d77d 100644 --- a/src/eko/io/manipulate.py +++ b/src/eko/io/manipulate.py @@ -1,7 +1,9 @@ """Manipulate output generate by EKO.""" + +import copy import logging import warnings -from typing import Callable, Optional, Union +from typing import Callable, Optional import numpy as np import numpy.typing as npt @@ -9,7 +11,7 @@ from .. import basis_rotation as br from .. import interpolation from ..interpolation import XGrid -from .struct import EKO, Operator +from .struct import Operator logger = logging.getLogger(__name__) @@ -18,13 +20,13 @@ SIMGRID_ROTATION = "ij,ajbk,kl->aibl" """Simultaneous grid rotation contraction indices.""" -Basis = Union[XGrid, npt.NDArray] - -def rotation(new: Optional[Basis], old: Basis, check: Callable, compute: Callable): +def rotation( + new: Optional[XGrid], old: XGrid, check: Callable, compute: Callable +) -> npt.NDArray: """Define grid rotation. - This function returns the new grid to be assigned and the rotation computed, + This function returns the necessary rotation, if the checks for a non-trivial new grid are passed. However, the check and the computation are delegated respectively to the @@ -32,21 +34,23 @@ def rotation(new: Optional[Basis], old: Basis, check: Callable, compute: Callabl """ if new is None: - return old, None + return None if check(new, old): warnings.warn("The new grid is close to the current one") - return old, None + return None - return new, compute(new, old) + return compute(new, old) -def xgrid_check(new: Optional[XGrid], old: XGrid): +def xgrid_check(new: Optional[XGrid], old: XGrid) -> bool: """Check validity of new xgrid.""" return new is not None and len(new) == len(old) and np.allclose(new.raw, old.raw) -def xgrid_compute_rotation(new: XGrid, old: XGrid, interpdeg: int, swap: bool = False): +def xgrid_compute_rotation( + new: XGrid, old: XGrid, interpdeg: int, swap: bool = False +) -> npt.NDArray: """Compute rotation from old to new xgrid. By default, the roation is computed for a target xgrid. Whether the function @@ -61,81 +65,66 @@ def xgrid_compute_rotation(new: XGrid, old: XGrid, interpdeg: int, swap: bool = def xgrid_reshape( - eko: EKO, + elem: Operator, + xgrid: XGrid, + interpdeg: int, targetgrid: Optional[XGrid] = None, inputgrid: Optional[XGrid] = None, -): - """Reinterpolate operators on output and/or input grids. +) -> Operator: + """Reinterpolate the operator on output and/or input grid(s). Target corresponds to the output PDF. - - The operation is in-place. - """ - eko.assert_permissions(write=True) - # calling with no arguments is an error if targetgrid is None and inputgrid is None: raise ValueError("Nor inputgrid nor targetgrid was given") - interpdeg = eko.operator_card.configs.interpolation_polynomial_degree check = xgrid_check crot = xgrid_compute_rotation # construct matrices - newtarget, targetrot = rotation( + targetrot = rotation( targetgrid, - eko.bases.targetgrid, + xgrid, check, lambda new, old: crot(new, old, interpdeg), ) - newinput, inputrot = rotation( + inputrot = rotation( inputgrid, - eko.bases.inputgrid, + xgrid, check, lambda new, old: crot(new, old, interpdeg, swap=True), ) - # after the checks: if there is still nothing to do, skip if targetrot is None and inputrot is None: logger.debug("Nothing done.") - return - # if no rotation is done, the grids are not modified - if targetrot is not None: - eko.bases.targetgrid = newtarget - if inputrot is not None: - eko.bases.inputgrid = newinput + return copy.deepcopy(elem) # build new grid - for ep, elem in eko.items(): - assert elem is not None - - operands = [elem.operator] - operands_errs = [elem.error] + operands = [elem.operator] + operands_errs = [elem.error] - if targetrot is not None and inputrot is None: - contraction = TARGETGRID_ROTATION - elif inputrot is not None and targetrot is None: - contraction = INPUTGRID_ROTATION - else: - contraction = SIMGRID_ROTATION + if targetrot is not None and inputrot is None: + contraction = TARGETGRID_ROTATION + elif inputrot is not None and targetrot is None: + contraction = INPUTGRID_ROTATION + else: + contraction = SIMGRID_ROTATION - if targetrot is not None: - operands.insert(0, targetrot) - operands_errs.insert(0, targetrot) - if inputrot is not None: - operands.append(inputrot) - operands_errs.append(inputrot) - - new_operator = np.einsum(contraction, *operands, optimize="optimal") - if elem.error is not None: - new_error = np.einsum(contraction, *operands_errs, optimize="optimal") - else: - new_error = None + if targetrot is not None: + operands.insert(0, targetrot) + operands_errs.insert(0, targetrot) + if inputrot is not None: + operands.append(inputrot) + operands_errs.append(inputrot) - eko[ep] = Operator(operator=new_operator, error=new_error) + new_operator = np.einsum(contraction, *operands, optimize="optimal") + if elem.error is not None: + new_error = np.einsum(contraction, *operands_errs, optimize="optimal") + else: + new_error = None - eko.update() + return Operator(operator=new_operator, error=new_error) TARGETPIDS_ROTATION = "ca,ajbk->cjbk" @@ -145,107 +134,86 @@ def xgrid_reshape( def flavor_reshape( - eko: EKO, + elem: Operator, targetpids: Optional[npt.NDArray] = None, inputpids: Optional[npt.NDArray] = None, - update: bool = True, -): - """Change the operators to have in the output targetpids and/or in the input inputpids. - - The operation is in-place. +) -> Operator: + """Change the operator to have in the output targetpids and/or in the input inputpids. Parameters ---------- - eko : + elem : the operator to be rotated targetpids : target rotation specified in the flavor basis inputpids : input rotation specified in the flavor basis - update : - update :class:`~eko.io.struct.EKO` metadata after writing """ - eko.assert_permissions(write=True) - # calling with no arguments is an error if targetpids is None and inputpids is None: raise ValueError("Nor inputpids nor targetpids was given") # now check to the current status if targetpids is not None and np.allclose( - targetpids, np.eye(len(eko.bases.targetpids)) + targetpids, np.eye(elem.operator.shape[0]) ): targetpids = None warnings.warn("The new targetpids is close to current basis") - if inputpids is not None and np.allclose( - inputpids, np.eye(len(eko.bases.inputpids)) - ): + if inputpids is not None and np.allclose(inputpids, np.eye(elem.operator.shape[2])): inputpids = None warnings.warn("The new inputpids is close to current basis") # after the checks: if there is still nothing to do, skip if targetpids is None and inputpids is None: logger.debug("Nothing done.") - return + return copy.deepcopy(elem) # flip input around + inv_inputpids = np.zeros_like(inputpids) if inputpids is not None: inv_inputpids = np.linalg.inv(inputpids) # build new grid - for q2, elem in eko.items(): - ops = elem.operator - errs = elem.error - if targetpids is not None and inputpids is None: - ops = np.einsum(TARGETPIDS_ROTATION, targetpids, ops, optimize="optimal") - errs = ( - np.einsum(TARGETPIDS_ROTATION, targetpids, errs, optimize="optimal") - if errs is not None - else None - ) - elif inputpids is not None and targetpids is None: - ops = np.einsum(INPUTPIDS_ROTATION, ops, inv_inputpids, optimize="optimal") - errs = ( - np.einsum(INPUTPIDS_ROTATION, errs, inv_inputpids, optimize="optimal") - if errs is not None - else None - ) - else: - ops = np.einsum( - SIMPIDS_ROTATION, targetpids, ops, inv_inputpids, optimize="optimal" - ) - errs = ( - np.einsum( - SIMPIDS_ROTATION, - targetpids, - errs, - inv_inputpids, - optimize="optimal", - ) - if errs is not None - else None + ops = elem.operator + errs = elem.error + if targetpids is not None and inputpids is None: + ops = np.einsum(TARGETPIDS_ROTATION, targetpids, ops, optimize="optimal") + errs = ( + np.einsum(TARGETPIDS_ROTATION, targetpids, errs, optimize="optimal") + if errs is not None + else None + ) + elif inputpids is not None and targetpids is None: + ops = np.einsum(INPUTPIDS_ROTATION, ops, inv_inputpids, optimize="optimal") + errs = ( + np.einsum(INPUTPIDS_ROTATION, errs, inv_inputpids, optimize="optimal") + if errs is not None + else None + ) + else: + ops = np.einsum( + SIMPIDS_ROTATION, targetpids, ops, inv_inputpids, optimize="optimal" + ) + errs = ( + np.einsum( + SIMPIDS_ROTATION, + targetpids, + errs, + inv_inputpids, + optimize="optimal", ) + if errs is not None + else None + ) - eko[q2] = Operator(operator=ops, error=errs) - - # drop PIDs - keeping them int nevertheless - # there is no meaningful way to set them in general, after rotation - if inputpids is not None: - eko.bases.inputpids = np.array([0] * len(eko.bases.inputpids)) - if targetpids is not None: - eko.bases.targetpids = np.array([0] * len(eko.bases.targetpids)) - - if update: - eko.update() + return Operator(operator=ops, error=errs) -def to_evol(eko: EKO, source: bool = True, target: bool = False): +def to_evol(elem: Operator, source: bool = True, target: bool = False) -> Operator: """Rotate the operator into evolution basis. - This assigns also the pids. The operation is in-place. - Parameters ---------- - eko : + elem : the operator to be rotated source : rotate on the input tensor @@ -256,27 +224,15 @@ def to_evol(eko: EKO, source: bool = True, target: bool = False): # rotate inputpids = br.rotate_flavor_to_evolution if source else None targetpids = br.rotate_flavor_to_evolution if target else None - # prevent metadata update, since flavor_reshape has not enough information - # to determine inpupids and targetpids, and they will be updated after the - # call - flavor_reshape(eko, inputpids=inputpids, targetpids=targetpids, update=False) - # assign pids - if source: - eko.bases.inputpids = inputpids - if target: - eko.bases.targetpids = targetpids - - eko.update() + return flavor_reshape(elem, inputpids=inputpids, targetpids=targetpids) -def to_uni_evol(eko: EKO, source: bool = True, target: bool = False): +def to_uni_evol(elem: Operator, source: bool = True, target: bool = False) -> Operator: """Rotate the operator into evolution basis. - This assigns also the pids. The operation is in-place. - Parameters ---------- - eko : + elem : the operator to be rotated source : rotate on the input tensor @@ -287,14 +243,4 @@ def to_uni_evol(eko: EKO, source: bool = True, target: bool = False): # rotate inputpids = br.rotate_flavor_to_unified_evolution if source else None targetpids = br.rotate_flavor_to_unified_evolution if target else None - # prevent metadata update, since flavor_reshape has not enough information - # to determine inpupids and targetpids, and they will be updated after the - # call - flavor_reshape(eko, inputpids=inputpids, targetpids=targetpids, update=False) - # assign pids - if source: - eko.bases.inputpids = inputpids - if target: - eko.bases.targetpids = targetpids - - eko.update() + return flavor_reshape(elem, inputpids=inputpids, targetpids=targetpids) diff --git a/src/eko/io/metadata.py b/src/eko/io/metadata.py index 857f03b25..c95bbfcb5 100644 --- a/src/eko/io/metadata.py +++ b/src/eko/io/metadata.py @@ -1,4 +1,5 @@ """Define `eko.EKO` metadata.""" + import logging import os import pathlib @@ -8,7 +9,7 @@ import yaml from .. import version as vmod -from .bases import Bases +from ..interpolation import XGrid from .dictlike import DictLike from .paths import InternalPaths from .types import EvolutionPoint as EPoint @@ -34,10 +35,8 @@ class Metadata(DictLike): origin: EPoint """Inital scale.""" - bases: Bases - """Manipulation information, describing the current status of the EKO (e.g. - `inputgrid` and `targetgrid`). - """ + xgrid: XGrid + """Interpolation grid""" # tagging information _path: Optional[pathlib.Path] = None """Path to the open dir.""" diff --git a/src/eko/io/paths.py b/src/eko/io/paths.py index 67100fdaa..f4d5fc51f 100644 --- a/src/eko/io/paths.py +++ b/src/eko/io/paths.py @@ -1,4 +1,5 @@ """Define paths inside an `eko.EKO` object.""" + import pathlib from dataclasses import dataclass diff --git a/src/eko/io/raw.py b/src/eko/io/raw.py index fe969374a..a71d3d745 100644 --- a/src/eko/io/raw.py +++ b/src/eko/io/raw.py @@ -5,6 +5,7 @@ file, as opposed to structured YAML representing a specific runcard. """ + import os from pathlib import Path from tarfile import TarFile, TarInfo diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index 755fcaf72..e9fac3893 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -3,6 +3,7 @@ All energy scales in the runcards should be saved linearly, not the squared value, for consistency. Squares are consistenly taken inside. """ + from dataclasses import dataclass from math import nan from typing import List, Optional, Union @@ -104,7 +105,7 @@ class Configs(DictLike): class OperatorCard(DictLike): """Operator Card info.""" - mu0: float + init: EPoint """Initial scale.""" mugrid: List[EPoint] xgrid: interpolation.XGrid @@ -125,7 +126,7 @@ class OperatorCard(DictLike): @property def mu20(self): """Squared value of initial scale.""" - return self.mu0**2 + return self.init[0] ** 2 @property def mu2grid(self) -> npt.NDArray: @@ -193,23 +194,12 @@ def new_theory(self): alphas=old["alphas"], alphaem=alphaem, em_running=em_running, - scale=old["Qref"], - num_flavs_ref=old["nfref"], - max_num_flavs=old["MaxNfAs"], + ref=(old["Qref"], old["nfref"]), ) new["heavy"] = { - "num_flavs_init": nf_default(old["Q0"] ** 2.0, default_atlas(ms, ks)) - if old["nf0"] is None - else old["nf0"], - "num_flavs_max_pdf": old["MaxNfPdf"], "matching_ratios": self.heavies("k%sThr", old), "masses_scheme": old["HQ"], } - intrinsic = [] - for idx, q in enumerate(hq.FLAVORS): - if old.get(f"i{q}".upper()) == 1: - intrinsic.append(idx + 4) - new["heavy"]["intrinsic_flavors"] = intrinsic if old["HQ"] == "POLE": new["heavy"]["masses"] = [[m, nan] for m in ms] elif old["HQ"] == "MSBAR": @@ -233,17 +223,22 @@ def new_operator(self): old_th = self.theory new = {} - new["mu0"] = old_th["Q0"] + ms = self.heavies("m%s", old_th) + ks = self.heavies("k%sThr", old_th) + new["init"] = ( + old_th["Q0"], + ( + nf_default(old_th["Q0"] ** 2.0, default_atlas(ms, ks)) + if old_th["nf0"] is None + else old_th["nf0"] + ), + ) if "mugrid" in old: mugrid = old["mugrid"] else: mu2grid = old["Q2grid"] if "Q2grid" in old else old["mu2grid"] mugrid = np.sqrt(mu2grid).tolist() - new["mugrid"] = flavored_mugrid( - mugrid, - list(self.heavies("m%s", old_th)), - list(self.heavies("k%sThr", old_th)), - ) + new["mugrid"] = flavored_mugrid(mugrid, list(ms), list(ks)) new["configs"] = {} evmod = old_th["ModEv"] @@ -275,27 +270,6 @@ def new_operator(self): return OperatorCard.from_dict(new) -def update(theory: Union[RawCard, TheoryCard], operator: Union[RawCard, OperatorCard]): - """Update legacy runcards. - - This function is mainly defined for compatibility with the old interface. - Prefer direct usage of :class:`Legacy` in new code. - - Consecutive applications of this function yield identical results:: - - cards = update(theory, operator) - assert update(*cards) == cards - """ - if isinstance(theory, TheoryCard) or isinstance(operator, OperatorCard): - # if one is not a dict, both have to be new cards - assert isinstance(theory, TheoryCard) - assert isinstance(operator, OperatorCard) - return theory, operator - - cards = Legacy(theory, operator) - return cards.new_theory, cards.new_operator - - def default_atlas(masses: list, matching_ratios: list): r"""Create default landscape. diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index 11a0d6a30..3d332e8af 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -1,4 +1,5 @@ """Define output representation structures.""" + import contextlib import copy import logging @@ -15,7 +16,6 @@ from .. import interpolation from . import exceptions, raw from .access import AccessConfigs -from .bases import Bases from .inventory import Inventory from .items import Evolution, Matching, Operator, Recipe, Target from .metadata import Metadata @@ -104,20 +104,15 @@ def paths(self) -> InternalPaths: """Accessor for internal paths.""" return InternalPaths(self.metadata.path) - @property - def bases(self) -> Bases: - """Bases information.""" - return self.metadata.bases - @property def xgrid(self) -> interpolation.XGrid: """Momentum fraction internal grid.""" - return self.bases.xgrid + return self.metadata.xgrid @xgrid.setter def xgrid(self, value: interpolation.XGrid): """Set `xgrid` value.""" - self.bases.xgrid = value + self.metadata.xgrid = value self.update() @property @@ -271,7 +266,7 @@ def approx( Raises ------ ValueError - if multiple values are find in the neighbourhood + if multiple values are found in the neighbourhood """ eps = np.array([ep_ for ep_ in self if ep_[1] == ep[1]]) @@ -279,7 +274,9 @@ def approx( close = eps[np.isclose(ep[0], mu2s, rtol=rtol, atol=atol)] if len(close) == 1: - return tuple(close[0]) + found = close[0] + assert isinstance(found[0], float) + return (found[0], int(found[1])) if len(close) == 0: return None raise ValueError(f"Multiple values of Q2 have been found close to {ep}") @@ -536,8 +533,8 @@ def build(self) -> EKO: self.access.open = True metadata = Metadata( _path=self.path, - origin=(self.operator.mu20, self.theory.heavy.num_flavs_init), - bases=Bases(xgrid=self.operator.xgrid), + origin=(self.operator.init[0] ** 2, self.operator.init[1]), + xgrid=self.operator.xgrid, ) InternalPaths(self.path).bootstrap( theory=self.theory.raw, diff --git a/src/eko/io/types.py b/src/eko/io/types.py index 5573bafbb..20ac52db5 100644 --- a/src/eko/io/types.py +++ b/src/eko/io/types.py @@ -1,7 +1,7 @@ """Common type definitions, only used for static analysis.""" + import enum -import typing -from typing import Any, Dict, Generic, Tuple, TypeVar +from typing import Any, Dict, Generic, List, Tuple, TypeVar # Energy scales # ------------- @@ -22,8 +22,9 @@ Order = Tuple[int, int] FlavorsNumber = int FlavorIndex = int -IntrinsicFlavors = typing.List[FlavorIndex] -N3LOAdVariation = typing.Tuple[int, int, int, int] +IntrinsicFlavors = List[FlavorIndex] +N3LOAdVariation = Tuple[int, int, int, int] +OperatorLabel = Tuple[int, int] # Evolution coordinates # --------------------- diff --git a/src/eko/kernels/__init__.py b/src/eko/kernels/__init__.py index 7640727b5..594fbf1fa 100644 --- a/src/eko/kernels/__init__.py +++ b/src/eko/kernels/__init__.py @@ -1 +1,35 @@ """The solutions to the |DGLAP| equations.""" + +import enum + +from ..io.types import EvolutionMethod + + +class EvoMethods(enum.IntEnum): + """Enumerate evolution methods.""" + + ITERATE_EXACT = enum.auto() + ITERATE_EXPANDED = enum.auto() + PERTURBATIVE_EXACT = enum.auto() + PERTURBATIVE_EXPANDED = enum.auto() + TRUNCATED = enum.auto() + ORDERED_TRUNCATED = enum.auto() + DECOMPOSE_EXACT = enum.auto() + DECOMPOSE_EXPANDED = enum.auto() + + +def ev_method(s: EvolutionMethod) -> EvoMethods: + """Return the evolution method. + + Parameters + ---------- + s : + string representation + + Returns + ------- + i : + int representation + + """ + return EvoMethods[s.value.upper().replace("-", "_")] diff --git a/src/eko/kernels/as4_evolution_integrals.py b/src/eko/kernels/as4_evolution_integrals.py index f401de8c6..e33b14511 100644 --- a/src/eko/kernels/as4_evolution_integrals.py +++ b/src/eko/kernels/as4_evolution_integrals.py @@ -288,9 +288,7 @@ def j13_expanded(a1, a0, beta0, b_list): """ b1, b2, _ = b_list return (1 / beta0) * ( - (a1 - a0) - - b1 / 2 * (a1**2 - a0**2) - + (b1**2 - b2) / 3 * (a1**3 - a0**3) + (a1 - a0) - b1 / 2 * (a1**2 - a0**2) + (b1**2 - b2) / 3 * (a1**3 - a0**3) ) diff --git a/src/eko/kernels/non_singlet.py b/src/eko/kernels/non_singlet.py index 23b2ab47a..15b913438 100644 --- a/src/eko/kernels/non_singlet.py +++ b/src/eko/kernels/non_singlet.py @@ -4,9 +4,9 @@ import numpy as np from .. import beta +from . import EvoMethods from . import as4_evolution_integrals as as4_ei from . import evolution_integrals as ei -from . import utils @nb.njit(cache=True) @@ -281,7 +281,7 @@ def eko_ordered_truncated(gamma_ns, a1, a0, beta, order, ev_op_iterations): non-singlet ordered truncated EKO """ - a_steps = utils.geomspace(a0, a1, 1 + ev_op_iterations) + a_steps = np.geomspace(a0, a1, 1 + ev_op_iterations) U = U_vec(gamma_ns, beta, order) e = 1.0 al = a_steps[0] @@ -321,7 +321,7 @@ def eko_truncated(gamma_ns, a1, a0, beta, order, ev_op_iterations): non-singlet truncated EKO """ - a_steps = utils.geomspace(a0, a1, 1 + ev_op_iterations) + a_steps = np.geomspace(a0, a1, 1 + ev_op_iterations) U = U_vec(gamma_ns, beta, order) e = 1.0 al = a_steps[0] @@ -356,7 +356,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbation order - method : str + method : int method gamma_ns : numpy.ndarray non-singlet anomalous dimensions @@ -379,38 +379,38 @@ def dispatcher( # use always exact in LO if order[0] == 1: return lo_exact(gamma_ns, a1, a0, betalist) - if method == "ordered-truncated": + if method is EvoMethods.ORDERED_TRUNCATED: return eko_ordered_truncated( gamma_ns, a1, a0, betalist, order, ev_op_iterations ) - if method == "truncated": + if method is EvoMethods.TRUNCATED: return eko_truncated(gamma_ns, a1, a0, betalist, order, ev_op_iterations) # NLO if order[0] == 2: if method in [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", + EvoMethods.ITERATE_EXPANDED, + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.PERTURBATIVE_EXPANDED, ]: return nlo_expanded(gamma_ns, a1, a0, betalist) - # if method in ["iterate-exact", "decompose-exact", "perturbative-exact"]: + # exact is left return nlo_exact(gamma_ns, a1, a0, betalist) # NNLO if order[0] == 3: if method in [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", + EvoMethods.ITERATE_EXPANDED, + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.PERTURBATIVE_EXPANDED, ]: return nnlo_expanded(gamma_ns, a1, a0, betalist) return nnlo_exact(gamma_ns, a1, a0, betalist) # N3LO if order[0] == 4: if method in [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", + EvoMethods.ITERATE_EXPANDED, + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.PERTURBATIVE_EXPANDED, ]: return n3lo_expanded(gamma_ns, a1, a0, betalist) return n3lo_exact(gamma_ns, a1, a0, betalist) diff --git a/src/eko/kernels/non_singlet_qed.py b/src/eko/kernels/non_singlet_qed.py index 36d4d3c35..d81d5076b 100644 --- a/src/eko/kernels/non_singlet_qed.py +++ b/src/eko/kernels/non_singlet_qed.py @@ -1,10 +1,10 @@ """Collection of QED non-singlet EKOs.""" + import numba as nb import numpy as np from .. import beta from . import non_singlet as ns -from . import utils @nb.njit(cache=True) @@ -146,7 +146,7 @@ def as4_exact(gamma_ns, a1, a0, beta): @nb.njit(cache=True) def dispatcher( order, - method, + _method, gamma_ns, as_list, aem_half, @@ -164,7 +164,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbation order - method : str + method : int method gamma_ns : numpy.ndarray non-singlet anomalous dimensions @@ -276,7 +276,7 @@ def exact(order, gamma_ns, as_list, aem_half, nf, ev_op_iterations, mu2_from, mu e_ns : complex non-singlet EKO """ - mu2_steps = utils.geomspace(mu2_from, mu2_to, 1 + ev_op_iterations) + mu2_steps = np.geomspace(mu2_from, mu2_to, 1 + ev_op_iterations) res = 1.0 for step in range(1, ev_op_iterations + 1): aem = aem_half[step - 1] diff --git a/src/eko/kernels/singlet.py b/src/eko/kernels/singlet.py index 159135dc6..e637af046 100644 --- a/src/eko/kernels/singlet.py +++ b/src/eko/kernels/singlet.py @@ -6,9 +6,9 @@ from ekore import anomalous_dimensions as ad from .. import beta +from . import EvoMethods from . import as4_evolution_integrals as as4_ei from . import evolution_integrals as ei -from . import utils @nb.njit(cache=True) @@ -323,7 +323,7 @@ def eko_iterate(gamma_singlet, a1, a0, beta_vec, order, ev_op_iterations): numpy.ndarray singlet iterated (exact) EKO """ - a_steps = utils.geomspace(a0, a1, 1 + ev_op_iterations) + a_steps = np.geomspace(a0, a1, 1 + ev_op_iterations) e = np.identity(2, np.complex_) al = a_steps[0] for ah in a_steps[1:]: @@ -500,7 +500,7 @@ def eko_perturbative( uk = u_vec(r, ev_op_max_order) e = np.identity(2, np.complex_) # iterate elements - a_steps = utils.geomspace(a0, a1, 1 + ev_op_iterations) + a_steps = np.geomspace(a0, a1, 1 + ev_op_iterations) al = a_steps[0] for ah in a_steps[1:]: e0 = lo_exact(gamma_singlet, ah, al, beta) @@ -542,7 +542,7 @@ def eko_truncated(gamma_singlet, a1, a0, beta, order, ev_op_iterations): u1 = np.ascontiguousarray(u[1]) e = np.identity(2, np.complex_) # iterate elements - a_steps = utils.geomspace(a0, a1, 1 + ev_op_iterations) + a_steps = np.geomspace(a0, a1, 1 + ev_op_iterations) al = a_steps[0] for ah in a_steps[1:]: e0 = np.ascontiguousarray(lo_exact(gamma_singlet, ah, al, beta)) @@ -580,7 +580,7 @@ def dispatcher( # pylint: disable=too-many-return-statements ---------- order : tuple(int,int) perturbative order - method : str + method : int method gamma_singlet : numpy.ndarray singlet anomalous dimensions matrices @@ -610,9 +610,9 @@ def dispatcher( # pylint: disable=too-many-return-statements return lo_exact(gamma_singlet, a1, a0, betalist) # Common method for NLO and NNLO - if method in ["iterate-exact", "iterate-expanded"]: + if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: return eko_iterate(gamma_singlet, a1, a0, betalist, order, ev_op_iterations) - if method == "perturbative-exact": + if method is EvoMethods.PERTURBATIVE_EXACT: return eko_perturbative( gamma_singlet, a1, @@ -623,7 +623,7 @@ def dispatcher( # pylint: disable=too-many-return-statements ev_op_max_order, True, ) - if method == "perturbative-expanded": + if method is EvoMethods.PERTURBATIVE_EXPANDED: return eko_perturbative( gamma_singlet, a1, @@ -634,19 +634,19 @@ def dispatcher( # pylint: disable=too-many-return-statements ev_op_max_order, False, ) - if method in ["truncated", "ordered-truncated"]: + if method in [EvoMethods.TRUNCATED, EvoMethods.ORDERED_TRUNCATED]: return eko_truncated(gamma_singlet, a1, a0, betalist, order, ev_op_iterations) # These methods are scattered for nlo and nnlo - if method == "decompose-exact": + if method is EvoMethods.DECOMPOSE_EXACT: if order[0] == 2: return nlo_decompose_exact(gamma_singlet, a1, a0, betalist) - elif order[0] == 3: + if order[0] == 3: return nnlo_decompose_exact(gamma_singlet, a1, a0, betalist) return n3lo_decompose_exact(gamma_singlet, a1, a0, nf) - if method == "decompose-expanded": + if method is EvoMethods.DECOMPOSE_EXPANDED: if order[0] == 2: return nlo_decompose_expanded(gamma_singlet, a1, a0, betalist) - elif order[0] == 3: + if order[0] == 3: return nnlo_decompose_expanded(gamma_singlet, a1, a0, betalist) return n3lo_decompose_expanded(gamma_singlet, a1, a0, nf) raise NotImplementedError("Selected method is not implemented") diff --git a/src/eko/kernels/singlet_qed.py b/src/eko/kernels/singlet_qed.py index d6e57c537..d63a2f1ac 100644 --- a/src/eko/kernels/singlet_qed.py +++ b/src/eko/kernels/singlet_qed.py @@ -1,10 +1,12 @@ """Collection of QED singlet EKOs.""" + import numba as nb import numpy as np from ekore import anomalous_dimensions as ad from .. import beta +from . import EvoMethods @nb.njit(cache=True) @@ -65,7 +67,7 @@ def dispatcher( a_half, nf, ev_op_iterations, - ev_op_max_order, + _ev_op_max_order, ): """Determine used kernel and call it. @@ -73,7 +75,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbative order - method : str + method : int method gamma_singlet : numpy.ndarray singlet anomalous dimensions matrices @@ -95,7 +97,7 @@ def dispatcher( e_s : numpy.ndarray singlet EKO """ - if method in ["iterate-exact", "iterate-expanded"]: + if method is EvoMethods.ITERATE_EXACT: return eko_iterate( gamma_singlet, as_list, a_half, nf, order, ev_op_iterations, 4 ) diff --git a/src/eko/kernels/utils.py b/src/eko/kernels/utils.py deleted file mode 100644 index 8b227199b..000000000 --- a/src/eko/kernels/utils.py +++ /dev/null @@ -1,26 +0,0 @@ -"""Utility functions.""" - -import numba as nb -import numpy as np - - -@nb.njit(cache=True) -def geomspace(start, end, num): - """Numba port of :func:`numpy.geomspace`. - - Parameters - ---------- - start : float - initial value - end : float - final value - num : int - steps - - Returns - ------- - geomspace : numpy.ndarray - logarithmic spaced list between `start` and `end` - - """ - return np.exp(np.linspace(np.log(start), np.log(end), num)) diff --git a/src/eko/kernels/valence_qed.py b/src/eko/kernels/valence_qed.py index 3a8482f68..186c70219 100644 --- a/src/eko/kernels/valence_qed.py +++ b/src/eko/kernels/valence_qed.py @@ -1,6 +1,8 @@ """Collection of QED valence EKOs.""" + import numba as nb +from . import EvoMethods from .singlet_qed import eko_iterate @@ -13,7 +15,7 @@ def dispatcher( a_half, nf, ev_op_iterations, - ev_op_max_order, + _ev_op_max_order, ): """ Determine used kernel and call it. @@ -22,7 +24,7 @@ def dispatcher( ---------- order : tuple(int,int) perturbative order - method : str + method : int method gamma_singlet : numpy.ndarray singlet anomalous dimensions matrices @@ -44,7 +46,7 @@ def dispatcher( e_v : numpy.ndarray singlet EKO """ - if method in ["iterate-exact", "iterate-expanded"]: + if method is EvoMethods.ITERATE_EXACT: return eko_iterate( gamma_valence, as_list, a_half, nf, order, ev_op_iterations, 2 ) diff --git a/src/eko/matchings.py b/src/eko/matchings.py index 9ef6b8f9e..270581c23 100644 --- a/src/eko/matchings.py +++ b/src/eko/matchings.py @@ -1,4 +1,5 @@ r"""Holds the classes that define the |FNS|.""" + import logging from dataclasses import dataclass from typing import List, Union diff --git a/src/eko/mellin.py b/src/eko/mellin.py index 01ec56ad4..4302dae01 100644 --- a/src/eko/mellin.py +++ b/src/eko/mellin.py @@ -222,8 +222,11 @@ class Path: def __init__(self, t, logx, axis_offset): self.t = t - # TODO: shall we use: 0.4 * 16.0 / ( - logx) ? - self.r = 0.4 * 16.0 / (1.0 - logx) + # The prescription suggested by :cite:`Abate` for r is 0.4 * M / ( - logx) + # with M the number of accurate digits; Maria Ubiali suggested in her thesis M = 16. + # However, this seems to yield unstable results for the OME in the large x region + # so we add an additional regularization, which makes the path less "edgy" there + self.r = 0.4 * 16.0 / (0.1 - logx) if axis_offset: self.o = 1.0 else: diff --git a/src/eko/member.py b/src/eko/member.py index edf8f89a3..f6aa44d36 100644 --- a/src/eko/member.py +++ b/src/eko/member.py @@ -1,4 +1,5 @@ """Atomic operator member.""" + import copy import operator from numbers import Number diff --git a/src/eko/msbar_masses.py b/src/eko/msbar_masses.py index 356a81019..63e1b72d1 100644 --- a/src/eko/msbar_masses.py +++ b/src/eko/msbar_masses.py @@ -1,4 +1,5 @@ r"""|RGE| for the |MSbar| masses.""" + from typing import List import numba as nb @@ -377,8 +378,8 @@ def compute( """ # TODO: sketch in the docs how the MSbar computation works with a figure. - mu2_ref = couplings.scale**2 - nf_ref: FlavorsNumber = couplings.num_flavs_ref + mu2_ref = couplings.ref[0] ** 2 + nf_ref: FlavorsNumber = couplings.ref[1] masses = np.concatenate((np.zeros(nf_ref - 3), np.full(6 - nf_ref, np.inf))) def sc(thr_masses): @@ -395,7 +396,7 @@ def sc(thr_masses): heavy_quarks = quark_names[3:] hq_idxs = np.arange(0, 3) if nf_ref > 4: - heavy_quarks = reversed(heavy_quarks) + heavy_quarks = "".join(reversed(heavy_quarks)) hq_idxs = reversed(hq_idxs) # loop on heavy quarks and compute the msbar masses diff --git a/src/eko/quantities/couplings.py b/src/eko/quantities/couplings.py index 449abab38..cbeb40a62 100644 --- a/src/eko/quantities/couplings.py +++ b/src/eko/quantities/couplings.py @@ -1,10 +1,11 @@ """Types and quantities related to theory couplings.""" + import dataclasses import enum -from typing import Optional from ..io.dictlike import DictLike -from ..io.types import FlavorsNumber, LinearScale, ReferenceRunning, Scalar +from ..io.types import EvolutionPoint as EPoint +from ..io.types import LinearScale, ReferenceRunning, Scalar Coupling = Scalar CouplingRef = ReferenceRunning[Coupling] @@ -20,15 +21,7 @@ class CouplingsInfo(DictLike): alphas: Coupling alphaem: Coupling - scale: LinearScale - max_num_flavs: FlavorsNumber - num_flavs_ref: Optional[FlavorsNumber] - r"""Number of active flavors at strong coupling reference scale. - - I.e. :math:`n_{f,\text{ref}}(\mu^2_{\text{ref}})`, formerly called - ``nfref``. - - """ + ref: EPoint em_running: bool = False @property diff --git a/src/eko/quantities/heavy_quarks.py b/src/eko/quantities/heavy_quarks.py index df0285649..7328f0f12 100644 --- a/src/eko/quantities/heavy_quarks.py +++ b/src/eko/quantities/heavy_quarks.py @@ -1,4 +1,5 @@ """Heavy quarks related quantities.""" + import enum from dataclasses import dataclass from typing import Generic, List, Sequence, TypeVar @@ -6,13 +7,7 @@ import numpy as np from ..io.dictlike import DictLike -from ..io.types import ( - FlavorsNumber, - IntrinsicFlavors, - LinearScale, - ReferenceRunning, - SquaredScale, -) +from ..io.types import FlavorsNumber, LinearScale, ReferenceRunning, SquaredScale FLAVORS = "cbt" @@ -90,16 +85,6 @@ class HeavyInfo(DictLike): """ - num_flavs_init: FlavorsNumber - r"""Number of active flavors at fitting scale. - - I.e. :math:`n_{f,\text{ref}}(\mu^2_0)`, formerly called ``nf0``. - - """ - num_flavs_max_pdf: FlavorsNumber - """Maximum number of quark PDFs.""" - intrinsic_flavors: IntrinsicFlavors - """List of intrinsic quark PDFs.""" masses: HeavyQuarkMasses """List of heavy quark masses.""" masses_scheme: QuarkMassScheme diff --git a/src/eko/runner/__init__.py b/src/eko/runner/__init__.py index a487cdbaf..1c331d17b 100644 --- a/src/eko/runner/__init__.py +++ b/src/eko/runner/__init__.py @@ -1,5 +1,6 @@ """Manage steps to DGLAP solution, and operator creation.""" -import os + +from pathlib import Path from typing import Union from ..io.runcards import OperatorCard, TheoryCard @@ -14,7 +15,7 @@ def solve( theory_card: Union[RawCard, TheoryCard], operators_card: Union[RawCard, OperatorCard], - path: os.PathLike, + path: Path, ): r"""Solve DGLAP equations in terms of evolution kernel operators (EKO). diff --git a/src/eko/runner/commons.py b/src/eko/runner/commons.py index c27b4c8a2..af547b9a6 100644 --- a/src/eko/runner/commons.py +++ b/src/eko/runner/commons.py @@ -1,4 +1,5 @@ """Runners common utilities.""" + import numpy as np from ..couplings import Couplings, couplings_mod_ev @@ -32,7 +33,7 @@ def atlas(theory: TheoryCard, operator: OperatorCard) -> Atlas: # TODO: cache result masses = runcards.masses(theory, operator.configs.evolution_method) matching_scales = np.power(theory.heavy.matching_ratios, 2.0) * np.array(masses) - return Atlas(matching_scales.tolist(), (operator.mu20, theory.heavy.num_flavs_init)) + return Atlas(matching_scales.tolist(), (operator.mu20, operator.init[1])) def couplings(theory: TheoryCard, operator: OperatorCard) -> Couplings: diff --git a/src/eko/runner/legacy.py b/src/eko/runner/legacy.py index 39659f121..44f91670b 100644 --- a/src/eko/runner/legacy.py +++ b/src/eko/runner/legacy.py @@ -1,8 +1,11 @@ """Main application class of eko.""" + import logging -import os +from pathlib import Path from typing import Union +from ekomark.data import update_runcards + from ..evolution_operator.grid import OperatorGrid from ..io import EKO, Operator, runcards from ..io.types import RawCard @@ -29,7 +32,7 @@ def __init__( self, theory_card: Union[RawCard, runcards.TheoryCard], operators_card: Union[RawCard, runcards.OperatorCard], - path: os.PathLike, + path: Path, ): """Initialize runner. @@ -43,8 +46,7 @@ def __init__( path where to store the computed operator """ - new_theory, new_operator = runcards.update(theory_card, operators_card) - new_theory.heavy.intrinsic_flavors = [4, 5, 6] + new_theory, new_operator = update_runcards(theory_card, operators_card) # Store inputs self.path = path @@ -69,7 +71,6 @@ def __init__( masses=masses, mass_scheme=new_theory.heavy.masses_scheme.value, thresholds_ratios=new_theory.heavy.squared_ratios, - intrinsic_flavors=new_theory.heavy.intrinsic_flavors, xif=new_theory.xif, configs=new_operator.configs, debug=new_operator.debug, diff --git a/src/eko/runner/managed.py b/src/eko/runner/managed.py index 2c3d2c313..c50012ffd 100644 --- a/src/eko/runner/managed.py +++ b/src/eko/runner/managed.py @@ -10,6 +10,7 @@ but not automatically performed. """ + from pathlib import Path from ..io.items import Target @@ -20,8 +21,6 @@ def solve(theory: TheoryCard, operator: OperatorCard, path: Path): """Solve DGLAP equations in terms of evolution kernel operators (EKO).""" - theory.heavy.intrinsic_flavors = [4, 5, 6] - with EKO.create(path) as builder: eko = builder.load_cards(theory, operator).build() # pylint: disable=E1101 recipes.create(eko) diff --git a/src/eko/runner/operators.py b/src/eko/runner/operators.py index 702c6479c..a315f6964 100644 --- a/src/eko/runner/operators.py +++ b/src/eko/runner/operators.py @@ -1,4 +1,5 @@ """Combine parts into operators.""" + from functools import reduce from typing import List @@ -19,7 +20,9 @@ def _retrieve( elements = [] for head in headers: inv = parts if isinstance(head, Evolution) else parts_matching - elements.append(inv[head]) + op = inv[head] + assert op is not None + elements.append(op) return elements diff --git a/src/eko/runner/parts.py b/src/eko/runner/parts.py index ccb18392e..75c4d8db8 100644 --- a/src/eko/runner/parts.py +++ b/src/eko/runner/parts.py @@ -9,19 +9,21 @@ :class:`OperatorMatrixElement` to simplify the computation and passing down parameters. """ + import numpy as np from .. import evolution_operator as evop from ..evolution_operator import matching_condition from ..evolution_operator import operator_matrix_element as ome from ..evolution_operator import physical +from ..evolution_operator.grid import Managers from ..io import EKO from ..io.items import Evolution, Matching, Operator from ..quantities.heavy_quarks import QuarkMassScheme from . import commons -def _managers(eko: EKO) -> dict: +def _managers(eko: EKO) -> Managers: """Collect managers for operator computation. .. todo:: @@ -30,39 +32,14 @@ def _managers(eko: EKO) -> dict: """ tcard = eko.theory_card ocard = eko.operator_card - return dict( - thresholds_config=commons.atlas(tcard, ocard), + return Managers( + atlas=commons.atlas(tcard, ocard), couplings=commons.couplings(tcard, ocard), - interpol_dispatcher=commons.interpolator(ocard), + interpolator=commons.interpolator(ocard), ) -def _blowup_info(eko: EKO) -> dict: - """Prepare common information to blow up to flavor basis. - - Note - ---- - ``intrinsic_range`` is a fully deprecated feature, here and anywhere else, - since a full range is already always used for backward evolution, and it is - not harmful to use it also for forward. - - Indeed, the only feature of non-intrinsic evolution is to absorb a - non-trivial boundary condition when an intrinsic PDF is defined. - But to achieve this, is sufficient to not specify any intrinsic boundary - condition at all, while if something is there, it is intuitive enough that - it will be consistently evolved. - - Moreover, since two different behavior are applied for the forward and - backward evolution, the intrinsic range is a "non-local" function, since it - does not depend only on the evolution segment, but also on the previous - evolution history (to determine if evolution is backward in flavor, - irrespectively of happening for an increasing or decreasing interval in - scale at fixed flavor). - """ - return dict(intrinsic_range=[4, 5, 6], qed=eko.theory_card.order[1] > 0) - - -def _evolution_configs(eko: EKO) -> dict: +def _evolve_configs(eko: EKO) -> dict: """Create configs for :class:`Operator`. .. todo:: @@ -93,17 +70,17 @@ def _evolution_configs(eko: EKO) -> dict: def evolve(eko: EKO, recipe: Evolution) -> Operator: """Compute evolution in isolation.""" op = evop.Operator( - _evolution_configs(eko), + _evolve_configs(eko), _managers(eko), recipe.as_atlas, is_threshold=recipe.cliff, ) op.compute() - binfo = _blowup_info(eko) + qed = eko.theory_card.order[1] > 0 res, err = physical.PhysicalOperator.ad_to_evol_map( - op.op_members, op.nf, op.q2_to, **binfo - ).to_flavor_basis_tensor(qed=binfo["qed"]) + op.op_members, op.nf, op.q2_to, qed + ).to_flavor_basis_tensor(qed) return Operator(res, err) @@ -118,9 +95,8 @@ def _matching_configs(eko: EKO) -> dict: tcard = eko.theory_card ocard = eko.operator_card return dict( - **_evolution_configs(eko), + **_evolve_configs(eko), backward_inversion=ocard.configs.inversion_method, - intrinsic_range=tcard.heavy.intrinsic_flavors, ) @@ -147,10 +123,9 @@ def match(eko: EKO, recipe: Matching) -> Operator: eko.theory_card.heavy.masses_scheme is QuarkMassScheme.MSBAR, ) op.compute() - - binfo = _blowup_info(eko) + qed = eko.theory_card.order[1] > 0 res, err = matching_condition.MatchingCondition.split_ad_to_evol_map( - op.op_members, op.nf, recipe.scale, **binfo - ).to_flavor_basis_tensor(qed=binfo["qed"]) + op.op_members, op.nf, recipe.scale, qed + ).to_flavor_basis_tensor(qed) return Operator(res, err) diff --git a/src/eko/runner/recipes.py b/src/eko/runner/recipes.py index 9c0b11170..1f83e75dd 100644 --- a/src/eko/runner/recipes.py +++ b/src/eko/runner/recipes.py @@ -1,4 +1,5 @@ """Recipes containing instructions for atomic computations.""" + from typing import List from ..io.items import Evolution, Matching, Recipe diff --git a/src/eko/scale_variations/__init__.py b/src/eko/scale_variations/__init__.py index a271402c3..8d3f01556 100644 --- a/src/eko/scale_variations/__init__.py +++ b/src/eko/scale_variations/__init__.py @@ -3,31 +3,34 @@ A Mathematica snippet to check the formulas is available in the extras folder. """ + import enum +from typing import Any, Dict +from ..io.types import ScaleVariationsMethod from . import expanded, exponentiated class Modes(enum.IntEnum): - """Enumerate scale Variation modes.""" + """Enumerate scale variation modes.""" unvaried = enum.auto() exponentiated = enum.auto() expanded = enum.auto() -def sv_mode(s): +def sv_mode(s: ScaleVariationsMethod) -> Modes: """Return the scale variation mode. Parameters ---------- - s : str + s : string representation Returns ------- - enum.IntEnum - enum representation + i : + int representation """ if s is not None: @@ -35,10 +38,12 @@ def sv_mode(s): return Modes.unvaried -class ModeMixin: +class ScaleVariationModeMixin: """Mixin to cast scale variation mode.""" + config: Dict[str, Any] + @property - def sv_mode(self): + def sv_mode(self) -> Modes: """Return the scale variation mode.""" return sv_mode(self.config["ModSV"]) diff --git a/src/eko/scale_variations/expanded.py b/src/eko/scale_variations/expanded.py index f3a6be145..2192833bd 100644 --- a/src/eko/scale_variations/expanded.py +++ b/src/eko/scale_variations/expanded.py @@ -88,12 +88,8 @@ def variation_as3(gamma, L, beta0, beta1, g0e2, g0e3, g1g0, g0g1): """ return ( gamma[2] * L - + (1.0 / 2.0) - * (beta1 * gamma[0] + 2.0 * beta0 * gamma[1] + g1g0 + g0g1) - * L**2 - + (1.0 / 6.0) - * (2.0 * beta0**2 * gamma[0] + 3.0 * beta0 * g0e2 + g0e3) - * L**3 + + (1.0 / 2.0) * (beta1 * gamma[0] + 2.0 * beta0 * gamma[1] + g1g0 + g0g1) * L**2 + + (1.0 / 6.0) * (2.0 * beta0**2 * gamma[0] + 3.0 * beta0 * g0e2 + g0e3) * L**3 ) diff --git a/src/eko/scale_variations/exponentiated.py b/src/eko/scale_variations/exponentiated.py index 7efb88e79..fe42fe03b 100644 --- a/src/eko/scale_variations/exponentiated.py +++ b/src/eko/scale_variations/exponentiated.py @@ -1,4 +1,5 @@ r"""Contains the scale variation for ``ModSV=exponentiated``.""" + import numba as nb from .. import beta diff --git a/src/ekobox/apply.py b/src/ekobox/apply.py index 336900798..bf9f2083d 100644 --- a/src/ekobox/apply.py +++ b/src/ekobox/apply.py @@ -1,10 +1,14 @@ """Apply operator evolution to PDF set.""" +from dataclasses import dataclass +from typing import Dict, Optional, Union + import numpy as np from eko import basis_rotation as br from eko import interpolation from eko.io import EKO +from eko.io.types import EvolutionPoint def apply_pdf( @@ -49,6 +53,17 @@ def apply_pdf( CONTRACTION = "ajbk,bk" +_PdfLabel = Union[int, str] +"""PDF identifier: either PID or label.""" + + +@dataclass +class PdfResult: + """Helper class to collect PDF results.""" + + pdfs: Dict[_PdfLabel, float] + errors: Optional[Dict[_PdfLabel, float]] = None + def apply_pdf_flavor( eko: EKO, lhapdf_like, targetgrid=None, flavor_rotation=None, labels=None @@ -76,60 +91,60 @@ def apply_pdf_flavor( output PDFs and their associated errors for the computed mu2grid """ # create pdfs - pdfs = np.zeros((len(eko.bases.inputpids), len(eko.bases.inputgrid))) - for j, pid in enumerate(eko.bases.inputpids): + pdfs = np.zeros((len(br.flavor_basis_pids), len(eko.xgrid))) + for j, pid in enumerate(br.flavor_basis_pids): if not lhapdf_like.hasFlavor(pid): continue pdfs[j] = np.array( - [lhapdf_like.xfxQ2(pid, x, eko.mu20) / x for x in eko.bases.inputgrid.raw] + [lhapdf_like.xfxQ2(pid, x, eko.mu20) / x for x in eko.xgrid.raw] ) # build output - out_grid = {} + out_grid: Dict[EvolutionPoint, PdfResult] = {} for ep, elem in eko.items(): pdf_final = np.einsum(CONTRACTION, elem.operator, pdfs, optimize="optimal") if elem.error is not None: error_final = np.einsum(CONTRACTION, elem.error, pdfs, optimize="optimal") else: error_final = None - out_grid[ep] = { - "pdfs": dict(zip(eko.bases.targetpids, pdf_final)), - "errors": None, - } + out_grid[ep] = PdfResult(dict(zip(br.flavor_basis_pids, pdf_final))) if error_final is not None: - out_grid[ep]["errors"] = dict(zip(eko.bases.targetpids, error_final)) + out_grid[ep].errors = dict(zip(br.flavor_basis_pids, error_final)) qed = eko.theory_card.order[1] > 0 # rotate to evolution basis if flavor_rotation is not None: for q2, op in out_grid.items(): pdf = flavor_rotation @ np.array( - [op["pdfs"][pid] for pid in br.flavor_basis_pids] + [op.pdfs[pid] for pid in br.flavor_basis_pids] ) - if labels is None: - labels = list(range(flavor_rotation.shape[0])) - op["pdfs"] = dict(zip(labels, pdf)) - if op["errors"] is not None: + if not qed: + evol_basis = br.evol_basis + else: + evol_basis = br.unified_evol_basis + op.pdfs = dict(zip(evol_basis, pdf)) + if op.errors is not None: errors = flavor_rotation @ np.array( - [op["errors"][pid] for pid in br.flavor_basis_pids] + [op.errors[pid] for pid in br.flavor_basis_pids] ) - op["errors"] = dict(zip(labels, errors)) + op.errors = dict(zip(evol_basis, errors)) # rotate/interpolate to target grid if targetgrid is not None: b = interpolation.InterpolatorDispatcher( - xgrid=eko.bases.targetgrid, + xgrid=eko.xgrid, polynomial_degree=eko.operator_card.configs.interpolation_polynomial_degree, mode_N=False, ) rot = b.get_interpolation(targetgrid) for evpdf in out_grid.values(): - for pdf_label in evpdf["pdfs"]: - evpdf["pdfs"][pdf_label] = np.matmul(rot, evpdf["pdfs"][pdf_label]) - if evpdf["errors"] is not None: - evpdf["errors"][pdf_label] = np.matmul( - rot, evpdf["errors"][pdf_label] - ) - - return out_grid + for pdf_label in evpdf.pdfs: + evpdf.pdfs[pdf_label] = np.matmul(rot, evpdf.pdfs[pdf_label]) + if evpdf.errors is not None: + evpdf.errors[pdf_label] = np.matmul(rot, evpdf.errors[pdf_label]) + # cast back to be backward compatible + real_out_grid = {} + for ep, res in out_grid.items(): + real_out_grid[ep] = {"pdfs": res.pdfs, "errors": res.errors} + return real_out_grid diff --git a/src/ekobox/cards.py b/src/ekobox/cards.py index c7536bc50..86233c0df 100644 --- a/src/ekobox/cards.py +++ b/src/ekobox/cards.py @@ -1,4 +1,5 @@ """Tools to generate runcards.""" + import os from math import nan @@ -13,14 +14,9 @@ couplings=dict( alphas=0.118, alphaem=0.007496252, - scale=91.2, - num_flavs_ref=5, - max_num_flavs=6, + ref=(91.2, 5), ), heavy=dict( - num_flavs_init=4, - num_flavs_max_pdf=6, - intrinsic_flavors=[4], masses=[ReferenceRunning([mq, nan]) for mq in (2.0, 4.5, 173.07)], masses_scheme="POLE", matching_ratios=[1.0, 1.0, 1.0], @@ -32,7 +28,7 @@ ) _operator = dict( - mu0=1.65, + init=(1.65, 4), mugrid=[(100.0, 5)], xgrid=np.geomspace(1e-7, 1.0, 50).tolist(), configs=dict( diff --git a/src/ekobox/cli/__init__.py b/src/ekobox/cli/__init__.py index 241ca45cc..8d0e22df7 100644 --- a/src/ekobox/cli/__init__.py +++ b/src/ekobox/cli/__init__.py @@ -1,3 +1,4 @@ """EKO CLI definition.""" + from . import convert, inspect, log, run, runcards from .base import command diff --git a/src/ekobox/cli/base.py b/src/ekobox/cli/base.py index e1876eb73..34642626d 100644 --- a/src/ekobox/cli/base.py +++ b/src/ekobox/cli/base.py @@ -1,4 +1,5 @@ """Base command definition.""" + import click CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) diff --git a/src/ekobox/cli/convert.py b/src/ekobox/cli/convert.py index eded7997c..f8411bf91 100644 --- a/src/ekobox/cli/convert.py +++ b/src/ekobox/cli/convert.py @@ -1,4 +1,5 @@ """Upgrade old files.""" + import pathlib from typing import Optional diff --git a/src/ekobox/cli/inspect.py b/src/ekobox/cli/inspect.py index f37f09cce..c355fce61 100644 --- a/src/ekobox/cli/inspect.py +++ b/src/ekobox/cli/inspect.py @@ -1,4 +1,5 @@ """Launch EKO calculations, with legacy mu2grid mode.""" + import pathlib import click @@ -27,7 +28,7 @@ def subcommand(ctx, path: pathlib.Path): @click.pass_obj def sub_mu2(operator: EKO): """Check operator's mu2grid.""" - rich.print_json(data=operator.mu2grid.tolist()) + rich.print_json(data=operator.mu2grid) @subcommand.command("cards") diff --git a/src/ekobox/cli/library.py b/src/ekobox/cli/library.py index 911f5ccaa..04cc980d7 100644 --- a/src/ekobox/cli/library.py +++ b/src/ekobox/cli/library.py @@ -1,4 +1,5 @@ """Library of reusable options and elements.""" + import pathlib import click diff --git a/src/ekobox/cli/log.py b/src/ekobox/cli/log.py index 38a63d4a3..2dcd7d9e0 100644 --- a/src/ekobox/cli/log.py +++ b/src/ekobox/cli/log.py @@ -1,4 +1,5 @@ """Logging settings.""" + import logging from rich.console import Console diff --git a/src/ekobox/cli/run.py b/src/ekobox/cli/run.py index 16e11c5fd..44cfe216e 100644 --- a/src/ekobox/cli/run.py +++ b/src/ekobox/cli/run.py @@ -1,4 +1,5 @@ """Launch EKO calculations, with legacy mu2grid mode.""" + import pathlib from typing import Sequence @@ -52,11 +53,11 @@ def subcommand(paths: Sequence[pathlib.Path]): else: output = operator.parent / OUTPUT - theory = yaml.safe_load(theory.read_text(encoding="utf-8")) - if "order" in theory: - theory = TheoryCard.from_dict(theory) - operator = yaml.safe_load(operator.read_text(encoding="utf-8")) - if "configs" in operator: - operator = OperatorCard.from_dict(operator) + tc = yaml.safe_load(theory.read_text(encoding="utf-8")) + if "order" in tc: + tc = TheoryCard.from_dict(tc) + oc = yaml.safe_load(operator.read_text(encoding="utf-8")) + if "configs" in oc: + oc = OperatorCard.from_dict(oc) - eko.solve(theory, operator, path=output) + eko.solve(tc, oc, path=output) diff --git a/src/ekobox/cli/runcards.py b/src/ekobox/cli/runcards.py index 1ad7d91d4..99db353bd 100644 --- a/src/ekobox/cli/runcards.py +++ b/src/ekobox/cli/runcards.py @@ -1,7 +1,10 @@ """Subcommand to manage runcards.""" + import logging import pathlib +import numpy as np + from .. import cards from . import library as lib from .base import command @@ -33,7 +36,7 @@ def sub_example(destination: pathlib.Path): theory.order = (1, 0) cards.dump(theory.raw, path=destination / "theory.yaml") operator = cards.example.operator() - operator.mu0 = 1.65 - operator.mu2grid = [1e5] + operator.init = (1.65, 4) + operator.mugrid = [(np.sqrt(1e5), 5)] cards.dump(operator.raw, path=destination / "operator.yaml") _logger.info(f"Runcards generated to '{destination}'") diff --git a/src/ekobox/evol_pdf.py b/src/ekobox/evol_pdf.py index 49cda53b6..9da6dda65 100644 --- a/src/ekobox/evol_pdf.py +++ b/src/ekobox/evol_pdf.py @@ -1,14 +1,15 @@ """Tools to evolve actual PDFs.""" + import pathlib -from collections import defaultdict import numpy as np -import eko from eko import basis_rotation as br from eko.io import EKO +from eko.runner import managed from . import apply, genpdf, info_file +from .utils import regroup_evolgrid DEFAULT_NAME = "eko.tar" @@ -47,6 +48,18 @@ def evolve_pdfs( info_update : dict dict of info to add or update to default info file """ + # separate by nf the evolgrid (and order per nf/q) + q2block_per_nf = regroup_evolgrid(operators_card.mugrid) + + # check we have disjoint scale ranges + nfs = list(q2block_per_nf.keys()) + for j in range(len(nfs) - 1): + # equal points are allowed by LHAPDF + if q2block_per_nf[nfs[j]][-1] > q2block_per_nf[nfs[j + 1]][0]: + raise ValueError( + f"Last scale point for nf={nfs[j]} is bigger than first in nf={nfs[j+1]}" + ) + # update op and th cards if path is not None: eko_path = pathlib.Path(path) @@ -55,17 +68,21 @@ def evolve_pdfs( else: if store_path is None: raise ValueError("'store_path' required if 'path' is not provided.") - eko.solve(theory_card, operators_card, path=store_path) + managed.solve(theory_card, operators_card, path=store_path) eko_path = store_path # apply PDF to eko evolved_PDF_list = [] + q2block_per_nf = {} with EKO.read(eko_path) as eko_output: for initial_PDF in initial_PDF_list: evolved_PDF_list.append( apply.apply_pdf(eko_output, initial_PDF, targetgrid) ) + # separate by nf the evolgrid (and order per nf/q) + q2block_per_nf = regroup_evolgrid(eko_output.evolgrid) # pylint: disable=E1101 + # update info file if targetgrid is None: targetgrid = operators_card.xgrid @@ -80,9 +97,6 @@ def evolve_pdfs( info_update=info_update, ) - # separate by nf the evolgrid (and order per nf/q) - q2block_per_nf = regroup_evolgrid(eko_output.evolgrid) - # write all replicas all_member_blocks = [] for evolved_PDF in evolved_PDF_list: @@ -96,14 +110,6 @@ def evolve_pdfs( genpdf.install_pdf(name) -def regroup_evolgrid(evolgrid: list): - """Split evolution points by nf and sort by scale.""" - by_nf = defaultdict(list) - for q, nf in sorted(evolgrid, key=lambda ep: ep[1]): - by_nf[nf].append(q) - return {nf: sorted(qs) for nf, qs in by_nf.items()} - - def collect_blocks(evolved_PDF: dict, q2block_per_nf: dict, xgrid: list): """Collect all LHAPDF blocks for a given replica. @@ -130,7 +136,7 @@ def pdf_xq2(pid, x, Q2): pdf_xq2, xgrid=xgrid, sorted_q2grid=q2grid, - pids=br.flavor_basis_pids, + pids=np.array(br.flavor_basis_pids), ) all_blocks.append(block) return all_blocks diff --git a/src/ekobox/genpdf/__init__.py b/src/ekobox/genpdf/__init__.py index af94a410e..d6c427989 100644 --- a/src/ekobox/genpdf/__init__.py +++ b/src/ekobox/genpdf/__init__.py @@ -1,4 +1,5 @@ """Create fake PDF sets for debugging.""" + import copy import logging import pathlib @@ -16,7 +17,7 @@ def take_data( - parent_pdf_set: Optional[Union[str, dict]] = None, + parent_pdf_set=None, members: bool = False, xgrid: Optional[List[float]] = None, evolgrid: Optional[List[EPoint]] = None, @@ -62,7 +63,7 @@ def take_data( all_blocks.append( [ generate_block( - toylh.xfxQ2, xgrid, sorted_q2grid, br.flavor_basis_pids + toylh.xfxQ2, xgrid, sorted_q2grid, list(br.flavor_basis_pids) ) ] ) @@ -81,12 +82,12 @@ def take_data( all_blocks.append( [ generate_block( - lambda pid, x, Q2: 0.0 - if pid not in parent_pdf_set - else parent_pdf_set[pid](x, Q2), + lambda pid, x, Q2: ( + 0.0 if pid not in parent_pdf_set else parent_pdf_set[pid](x, Q2) + ), xgrid, sorted_q2grid, - br.flavor_basis_pids, + list(br.flavor_basis_pids), ) ] ) diff --git a/src/ekobox/genpdf/export.py b/src/ekobox/genpdf/export.py index 98bab23b0..f3ca8d31d 100644 --- a/src/ekobox/genpdf/export.py +++ b/src/ekobox/genpdf/export.py @@ -1,4 +1,5 @@ """PDF set writer.""" + import io import pathlib import re diff --git a/src/ekobox/genpdf/flavors.py b/src/ekobox/genpdf/flavors.py index 2798ccb19..6b7d90ebe 100644 --- a/src/ekobox/genpdf/flavors.py +++ b/src/ekobox/genpdf/flavors.py @@ -1,4 +1,5 @@ """Collection of flavor tools.""" + import copy import numpy as np diff --git a/src/ekobox/genpdf/load.py b/src/ekobox/genpdf/load.py index f4ecb9f74..988038998 100644 --- a/src/ekobox/genpdf/load.py +++ b/src/ekobox/genpdf/load.py @@ -1,4 +1,5 @@ """PDF set elements loaders.""" + import pathlib import numpy as np diff --git a/src/ekobox/info_file.py b/src/ekobox/info_file.py index 2f99d8377..16dde0197 100644 --- a/src/ekobox/info_file.py +++ b/src/ekobox/info_file.py @@ -1,6 +1,8 @@ """LHAPDF info file utilities.""" + import copy import math +from typing import Any, Dict import numpy as np @@ -8,6 +10,7 @@ from eko.io.runcards import OperatorCard, TheoryCard from .genpdf import load +from .utils import regroup_evolgrid def build( @@ -15,19 +18,19 @@ def build( operators_card: OperatorCard, num_members: int, info_update: dict, -): - """Generate a lhapdf info file from theory and operators card. +) -> dict: + """Generate a lhapdf info file. Parameters ---------- - theory_card : dict + theory_card : theory card - operators_card : dict - operators_card - num_members : int + operators_card : + operators card + num_members : number of pdf set members - info_update : dict - info to update + info_update : + additional info to update Returns ------- @@ -35,7 +38,9 @@ def build( info file in lhapdf format """ template_info = copy.deepcopy(load.template_info) - template_info["SetDesc"] = "Evolved PDF from " + str(operators_card.mu0) + " GeV" + template_info["SetDesc"] = ( + "Evolved PDF from " + str(operators_card.init[0]) + " GeV" + ) template_info["Authors"] = "" template_info["FlavorScheme"] = "variable" template_info.update(info_update) @@ -48,15 +53,42 @@ def build( template_info["OrderQCD"] = theory_card.order[0] - 1 template_info["QMin"] = round(math.sqrt(operators_card.mu2grid[0]), 4) template_info["QMax"] = round(math.sqrt(operators_card.mu2grid[-1]), 4) - template_info["MZ"] = theory_card.couplings.scale + template_info["MZ"] = theory_card.couplings.ref[0] template_info["MUp"] = 0.0 template_info["MDown"] = 0.0 template_info["MStrange"] = 0.0 template_info["MCharm"] = theory_card.heavy.masses.c.value template_info["MBottom"] = theory_card.heavy.masses.b.value template_info["MTop"] = theory_card.heavy.masses.t.value + # dump alphas + template_info.update(build_alphas(theory_card, operators_card)) + return template_info + + +def build_alphas( + theory_card: TheoryCard, + operators_card: OperatorCard, +) -> dict: + """Generate a couplings section of lhapdf info file. + + Parameters + ---------- + theory_card : dict + theory card + operators_card : dict + operators card + + Returns + ------- + dict + info file section in lhapdf format + """ + # start with meta stuff + template_info: Dict[str, Any] = {} template_info["AlphaS_MZ"] = theory_card.couplings.alphas template_info["AlphaS_OrderQCD"] = theory_card.order[0] - 1 + # prepare + evolgrid = regroup_evolgrid(operators_card.mugrid) evmod = couplings.couplings_mod_ev(operators_card.configs.evolution_method) quark_masses = [(x.value) ** 2 for x in theory_card.heavy.masses] sc = couplings.Couplings( @@ -67,19 +99,14 @@ def build( hqm_scheme=theory_card.heavy.masses_scheme, thresholds_ratios=np.power(list(iter(theory_card.heavy.matching_ratios)), 2.0), ) - alphas_values = np.array( - [ - 4.0 - * np.pi - * sc.a_s( - muf2, - ) - for muf2 in operators_card.mu2grid - ], - dtype=float, - ) - template_info["AlphaS_Vals"] = alphas_values.tolist() - template_info["AlphaS_Qs"] = np.array( - [mu for mu, _ in operators_card.mugrid] - ).tolist() + # add actual values + alphas_values = [] + alphas_qs = [] + for nf, mus in evolgrid.items(): + for mu in mus: + alphas_values.append(float(4.0 * np.pi * sc.a_s(mu * mu, nf_to=nf))) + alphas_qs.append(mu) + + template_info["AlphaS_Vals"] = alphas_values + template_info["AlphaS_Qs"] = alphas_qs return template_info diff --git a/src/ekobox/mock.py b/src/ekobox/mock.py index ad56ad0cb..06ba8fae9 100644 --- a/src/ekobox/mock.py +++ b/src/ekobox/mock.py @@ -1,4 +1,5 @@ """Mocking tools.""" + import numpy as np diff --git a/src/ekobox/utils.py b/src/ekobox/utils.py index 095e605e9..5a00314e7 100644 --- a/src/ekobox/utils.py +++ b/src/ekobox/utils.py @@ -1,5 +1,7 @@ """Generic utilities to work with EKOs.""" -import os + +from collections import defaultdict +from pathlib import Path from typing import Optional import numpy as np @@ -14,7 +16,7 @@ def ekos_product( eko_fin: EKO, rtol: float = 1e-6, atol: float = 1e-10, - path: Optional[os.PathLike] = None, + path: Optional[Path] = None, ): """Compute the product of two ekos. @@ -37,7 +39,7 @@ def ekos_product( # another kind of output which includes the theory and operator runcards) ep_match = eko_ini.approx( - (eko_fin.operator_card.mu0**2, eko_fin.theory_card.heavy.num_flavs_init), + (eko_fin.operator_card.init[0] ** 2, eko_fin.operator_card.init[1]), rtol=rtol, atol=atol, ) @@ -77,3 +79,11 @@ def ekos_product( if path is not None: final_eko.close() + + +def regroup_evolgrid(evolgrid: list): + """Split evolution points by nf and sort by scale.""" + by_nf = defaultdict(list) + for q, nf in sorted(evolgrid, key=lambda ep: ep[1]): + by_nf[nf].append(q) + return {nf: sorted(qs) for nf, qs in by_nf.items()} diff --git a/src/ekomark/__init__.py b/src/ekomark/__init__.py index f3c8b2d7c..7f002b449 100644 --- a/src/ekomark/__init__.py +++ b/src/ekomark/__init__.py @@ -1,4 +1,5 @@ """Benchmark package for eko.""" + from eko import basis_rotation as br diff --git a/src/ekomark/benchmark/external/LHA_utils.py b/src/ekomark/benchmark/external/LHA_utils.py index 39043394e..f58d44d3e 100644 --- a/src/ekomark/benchmark/external/LHA_utils.py +++ b/src/ekomark/benchmark/external/LHA_utils.py @@ -1,4 +1,5 @@ """Implementation of :cite:`Giele:2002hx` and :cite:`Dittmar:2005ed` (NNLO and polarized).""" + import pathlib import numpy as np diff --git a/src/ekomark/benchmark/external/apfel_utils.py b/src/ekomark/benchmark/external/apfel_utils.py index b209d54a9..6659b3e58 100644 --- a/src/ekomark/benchmark/external/apfel_utils.py +++ b/src/ekomark/benchmark/external/apfel_utils.py @@ -1,4 +1,5 @@ """|APFEL| interface.""" + import time import numpy as np diff --git a/src/ekomark/benchmark/external/lhapdf_utils.py b/src/ekomark/benchmark/external/lhapdf_utils.py index 6e327f86b..40a591070 100644 --- a/src/ekomark/benchmark/external/lhapdf_utils.py +++ b/src/ekomark/benchmark/external/lhapdf_utils.py @@ -1,4 +1,5 @@ """LHAPDF interface.""" + import numpy as np from eko import basis_rotation as br diff --git a/src/ekomark/benchmark/external/pegasus_utils.py b/src/ekomark/benchmark/external/pegasus_utils.py index 14be7c71d..373a3d334 100644 --- a/src/ekomark/benchmark/external/pegasus_utils.py +++ b/src/ekomark/benchmark/external/pegasus_utils.py @@ -1,4 +1,5 @@ """|Pegasus| interface.""" + import numpy as np from eko import basis_rotation as br diff --git a/src/ekomark/benchmark/runner.py b/src/ekomark/benchmark/runner.py index 180f439e6..2b003e1b3 100644 --- a/src/ekomark/benchmark/runner.py +++ b/src/ekomark/benchmark/runner.py @@ -1,4 +1,5 @@ """Abstract layer for running the benchmarks.""" + import functools import logging import os @@ -13,7 +14,6 @@ import eko from eko import EKO from eko import basis_rotation as br -from eko.io import manipulate from ekobox import apply from .. import pdfname @@ -116,22 +116,14 @@ def run_me(self, theory, ocard, _pdf): os.makedirs(output_path) # rotating to evolution basis if requested with EKO.edit(path) as out_copy: - change_lab = False - if self.rotate_to_evolution_basis: - qed = theory["QED"] > 0 - if not qed: - manipulate.to_evol(out_copy, source=True, target=True) - else: - manipulate.to_uni_evol(out_copy, source=True, target=True) - change_lab = True - save_operators_to_pdf( output_path, theory, ocard, out_copy, self.skip_pdfs(theory), - change_lab, + self.rotate_to_evolution_basis, + theory["QED"] > 0, ) else: # else we always rerun diff --git a/src/ekomark/data/__init__.py b/src/ekomark/data/__init__.py index 797409204..89fb6377b 100644 --- a/src/ekomark/data/__init__.py +++ b/src/ekomark/data/__init__.py @@ -1 +1,30 @@ """EKO database configuration.""" + +from typing import Union + +from eko.io.runcards import Legacy, OperatorCard, TheoryCard +from eko.io.types import RawCard + + +def update_runcards( + theory: Union[RawCard, TheoryCard], operator: Union[RawCard, OperatorCard] +): + """Update legacy runcards. + + This function is mainly defined for compatibility with the old interface. + Prefer direct usage of :class:`Legacy` in new code. + + Consecutive applications of this function yield identical results:: + + cards = update(theory, operator) + assert update(*cards) == cards + + """ + if isinstance(theory, TheoryCard) or isinstance(operator, OperatorCard): + # if one is not a dict, both have to be new cards + assert isinstance(theory, TheoryCard) + assert isinstance(operator, OperatorCard) + return theory, operator + + cards = Legacy(theory, operator) + return cards.new_theory, cards.new_operator diff --git a/src/ekomark/data/operators.py b/src/ekomark/data/operators.py index dfbbc6ad9..03ad4d349 100644 --- a/src/ekomark/data/operators.py +++ b/src/ekomark/data/operators.py @@ -1,4 +1,5 @@ """Operator card configurations.""" + from banana.data import cartesian_product, sql from eko import interpolation @@ -14,7 +15,7 @@ ev_op_max_order=10, ev_op_iterations=10, backward_inversion="expanded", - n_integration_cores=0, + n_integration_cores=1, debug_skip_non_singlet=False, debug_skip_singlet=False, mugrid=[10], diff --git a/src/ekomark/navigator/__init__.py b/src/ekomark/navigator/__init__.py index f1c70a907..de2b75f25 100644 --- a/src/ekomark/navigator/__init__.py +++ b/src/ekomark/navigator/__init__.py @@ -1,4 +1,5 @@ """ekomark specialization of the navigator.""" + import argparse import pathlib diff --git a/src/ekomark/navigator/glob.py b/src/ekomark/navigator/glob.py index ecb39b22f..a0c393884 100644 --- a/src/ekomark/navigator/glob.py +++ b/src/ekomark/navigator/glob.py @@ -1,3 +1,4 @@ """Global variables register.""" + app = None glob = globals() diff --git a/src/ekomark/navigator/navigator.py b/src/ekomark/navigator/navigator.py index c624c0737..27bcc61ef 100644 --- a/src/ekomark/navigator/navigator.py +++ b/src/ekomark/navigator/navigator.py @@ -1,4 +1,5 @@ """EKO implementation of navigator.""" + import os import webbrowser diff --git a/src/ekomark/plots.py b/src/ekomark/plots.py index 92a155de3..5e2bee420 100644 --- a/src/ekomark/plots.py +++ b/src/ekomark/plots.py @@ -1,6 +1,8 @@ """Plotting tools to show the evolved PDF and the computed operators.""" + import io import pprint +from typing import Dict, List import matplotlib.pyplot as plt import numpy as np @@ -9,6 +11,7 @@ from matplotlib.colors import LogNorm from eko import basis_rotation as br +from eko.io import manipulate from eko.io.struct import EKO @@ -209,7 +212,15 @@ def plot_operator(var_name, op, op_err, log_operator=True, abs_operator=True): return fig -def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=False): +def save_operators_to_pdf( + path, + theory, + ops, + me: EKO, + skip_pdfs, + rotate_to_evolution_basis: bool, + qed: bool = False, +): """Output all operator heatmaps to PDF. Parameters @@ -224,15 +235,12 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals DGLAP result skip_pdfs : list PDF to skip - change_lab : bool - set whether to rename the labels - + rotate_to_evolution_basis : bool + plot operators in evolution basis + qed : bool + plot operators in unified evolution basis, if the former is active """ - ops_names = list(me.bases.targetpids) - if np.allclose(ops_names, br.rotate_flavor_to_evolution): - ops_names = br.evol_basis_pids - else: - raise ValueError("Can not reconstruct PDF names") + ops_names = br.evol_basis_pids if rotate_to_evolution_basis else br.evol_basis_pids ops_id = f"o{ops['hash'][:6]}_t{theory['hash'][:6]}" path = f"{path}/{ops_id}.pdf" print(f"Plotting operators plots to {path}") @@ -244,16 +252,21 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals # plot the operators # it's necessary to reshuffle the eko output - for mu2 in me.mu2grid: - results = me[mu2].operator - errors = me[mu2].error + for ep, op in me.items(): + if rotate_to_evolution_basis: + if not qed: + op = manipulate.to_evol(op, source=True, target=True) + else: + op = manipulate.to_uni_evol(op, source=True, target=True) + results = op.operator + errors = op.error # loop on pids for label_out, res, res_err in zip(ops_names, results, errors): if label_out in skip_pdfs: continue - new_op = {} - new_op_err = {} + new_op: Dict[int, List[float]] = {} + new_op_err: Dict[int, List[float]] = {} # loop on xgrid point for j in range(len(me.xgrid)): # loop on pid in @@ -269,17 +282,10 @@ def save_operators_to_pdf(path, theory, ops, me: EKO, skip_pdfs, change_lab=Fals for label_in in ops_names: if label_in in skip_pdfs: continue - lab_in = label_in - lab_out = label_out - if change_lab: - index_in = br.evol_basis_pids.index(label_in) - index_out = br.evol_basis_pids.index(label_out) - lab_in = br.evol_basis[index_in] - lab_out = br.evol_basis[index_out] fig = None try: fig = plot_operator( - f"Operator ({lab_in};{lab_out}) µ_F^2 = {mu2} GeV^2", + f"Operator ({label_in};{label_out}) µ_F^2 = {ep[0]} GeV^2, nf = {ep[1]}", new_op[label_in], new_op_err[label_in], ) diff --git a/src/ekore/anomalous_dimensions/polarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/polarized/space_like/__init__.py index 1cb318930..68c9dc9f6 100644 --- a/src/ekore/anomalous_dimensions/polarized/space_like/__init__.py +++ b/src/ekore/anomalous_dimensions/polarized/space_like/__init__.py @@ -50,6 +50,7 @@ def gamma_ns(order, mode, n, nf): raise NotImplementedError("Non-singlet sector is not implemented") gamma_ns[1] = gamma_ns_1 if order[0] >= 3: + gamma_ns_2 = 0.0 if mode == 10101: gamma_ns_2 = as3.gamma_nsp(n, nf, cache) elif mode == 10201: diff --git a/src/ekore/anomalous_dimensions/polarized/space_like/as2.py b/src/ekore/anomalous_dimensions/polarized/space_like/as2.py index 95134d7ae..b031f26b2 100644 --- a/src/ekore/anomalous_dimensions/polarized/space_like/as2.py +++ b/src/ekore/anomalous_dimensions/polarized/space_like/as2.py @@ -59,8 +59,7 @@ def gamma_qg(n, nf, cache): gqg1_nfca = ( (S1**2 - S2 + Sp2m) * (n - 1) / (n * (n + 1)) - 4 * S1 / (n * (1 + n) ** 2) - - (-2 - 7 * n + 3 * n**2 - 4 * n**3 + n**4 + n**5) - / (n**3 * (1 + n) ** 3) + - (-2 - 7 * n + 3 * n**2 - 4 * n**3 + n**4 + n**5) / (n**3 * (1 + n) ** 3) ) * 2.0 gqg1_nfcf = ( (-(S1**2) + S2 + 2 * S1 / n) * (n - 1) / (n * (n + 1)) @@ -150,21 +149,12 @@ def gamma_gg(n, nf, cache): * S1 * (72 + 144 * n + 67 * n**2 + 134 * n**3 + 67 * n**4) / (9 * n**2 * (n + 1) ** 2) - - ( - 144 - + 258 * n - + 7 * n**2 - + 698 * n**3 - + 469 * n**4 - + 144 * n**5 - + 48 * n**6 - ) + - (144 + 258 * n + 7 * n**2 + 698 * n**3 + 469 * n**4 + 144 * n**5 + 48 * n**6) / (9 * n**3 * (1 + n) ** 3) ) * 0.5 ggg1_canf = ( -5 * S1 / 9 - + (-3 + 13 * n + 16 * n**2 + 6 * n**3 + 3 * n**4) - / (9 * n**2 * (1 + n) ** 2) + + (-3 + 13 * n + 16 * n**2 + 6 * n**3 + 3 * n**4) / (9 * n**2 * (1 + n) ** 2) ) * 4 ggg1_cfnf = (4 + 2 * n - 8 * n**2 + n**3 + 5 * n**4 + 3 * n**5 + n**6) / ( n**3 * (1 + n) ** 3 diff --git a/src/ekore/anomalous_dimensions/polarized/space_like/as3.py b/src/ekore/anomalous_dimensions/polarized/space_like/as3.py index a180c6782..76432acbf 100644 --- a/src/ekore/anomalous_dimensions/polarized/space_like/as3.py +++ b/src/ekore/anomalous_dimensions/polarized/space_like/as3.py @@ -177,9 +177,9 @@ def gamma_gq(N, nf, cache): """ S1 = c.get(c.S1, cache, N) - S2 = c.get(c.S1, cache, N) - S3 = c.get(c.S1, cache, N) - S4 = c.get(c.S1, cache, N) + S2 = c.get(c.S2, cache, N) + S3 = c.get(c.S3, cache, N) + S4 = c.get(c.S4, cache, N) B3 = (-(S1**3) - 3 * S1 * S2 - 2 * S3) / N B4 = (S1**4 + 6 * S1**2 * S2 + 3 * S2**2 + 8 * S1 * S3 + 6 * S4) / N E1 = S1 / N**2 + (-zeta2 + S2) / N @@ -256,8 +256,8 @@ def gamma_ps(N, nf, cache): """ S1 = c.get(c.S1, cache, N) - S2 = c.get(c.S1, cache, N) - S3 = c.get(c.S1, cache, N) + S2 = c.get(c.S2, cache, N) + S3 = c.get(c.S3, cache, N) B3 = (-(S1**3) - 3 * S1 * S2 - 2 * S3) / N B31 = ( -((1 / (1 + N) + S1) ** 3) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py index 32687e489..6a350f1ee 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py @@ -65,6 +65,7 @@ def gamma_ns(order, mode, n, nf, n3lo_ad_variation, use_fhmruvv=False): gamma_ns[1] = gamma_ns_1 # NNLO and beyond if order[0] >= 3: + gamma_ns_2 = 0.0 if mode == 10101: gamma_ns_2 = as3.gamma_nsp(n, nf, cache) elif mode == 10201: @@ -74,6 +75,7 @@ def gamma_ns(order, mode, n, nf, n3lo_ad_variation, use_fhmruvv=False): gamma_ns[2] = gamma_ns_2 # N3LO if order[0] >= 4: + gamma_ns_3 = 0.0 if use_fhmruvv: if mode == 10101: gamma_ns_3 = as4.fhmruvv.gamma_nsp( diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py index 01a115c5b..28f8533f4 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py @@ -18,7 +18,7 @@ def gamma_nsm(n, nf, cache): r"""Compute the |NLO| valence-like non-singlet anomalous dimension. - Implements Eq. (3.5) of :cite:`Moch:2004pa`. + Implements Eq. (3.6) of :cite:`Moch:2004pa`. Parameters ---------- diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py index b9bbd356d..98705f491 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py @@ -5,6 +5,7 @@ Note that the QCD colour factors have been hard-wired in the parametrizations. """ + import numba as nb import numpy as np diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py index 9b3b37517..5e46cbb15 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py @@ -3,6 +3,7 @@ For further documentation see :doc:`N3LO anomalous dimensions <../../../theory/N3LO_ad>` """ + import numba as nb import numpy as np diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/__init__.py index e92a55ffa..ec8949119 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/__init__.py @@ -2,6 +2,7 @@ Authors follow Pegasus convention and so there is an additional global minus sign with respect to our conventions. """ + import numba as nb import numpy as np diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggg.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggg.py index 1d2a2555b..640448e6a 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggg.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggg.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{gg}^{(3)}`.""" + import numba as nb from ......harmonics import cache as c diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggq.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggq.py index 97904f459..f34aea10a 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggq.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/ggq.py @@ -1,15 +1,29 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{gq}^{(3)}`.""" + import numba as nb +from eko.constants import zeta2 + from ......harmonics import cache as c -from ......harmonics.log_functions import lm12, lm13, lm14, lm15 +from ......harmonics.log_functions import ( + lm11, + lm12, + lm12m1, + lm13, + lm14, + lm14m1, + lm15, + lm15m1, +) @nb.njit(cache=True) def gamma_gq(n, nf, cache, variation): r"""Compute the |N3LO| gluon-quark singlet anomalous dimension. - The routine is taken from :cite:`Moch:2023tdj`. + The routine is taken from :cite:`Falcioni:2024xyt`. + Lower moments were published also in :cite:`Moch:2023tdj`. + Parameters ---------- @@ -39,76 +53,118 @@ def gamma_gq(n, nf, cache, variation): # Known large-x coefficients x1L5cff = 1.3443073 * 10 - 5.4869684 * 0.1 * nf x1L4cff = 3.7539831 * 10**2 - 3.4494742 * 10 * nf + 8.7791495 * 0.1 * nf2 + y1L5cff = 2.2222222 * 10 - 5.4869684 * 0.1 * nf + y1L4cff = 6.6242163 * 10**2 - 4.7992684 * 10 * nf + 8.7791495 * 0.1 * nf2 # Small-x, Casimir scaled from P_gg (approx. for bfkl1) bfkl0 = -8.3086173 * 10**3 / 2.25 bfkl1 = (-1.0691199 * 10**5 - nf * 9.9638304 * 10**2) / 2.25 + # Small-x double-logs with x^0 + x0L6cff = 5.2235940 * 10 - 7.3744856 * nf + x0L5cff = -2.9221399 * 10**2 + 1.8436214 * nf + x0L4cff = 7.3106077 * 10**3 - 3.7887135 * 10**2 * nf - 3.2438957 * 10 * nf2 + # The resulting part of the function P3GQ01 = ( +bfkl0 * (-(6 / (-1 + n) ** 4)) + bfkl1 * 2 / (-1 + n) ** 3 + + x0L6cff * 720 / n**7 + + x0L5cff * -120 / n**6 + + x0L4cff * 24 / n**5 + x1L4cff * lm14(n, S1, S2, S3, S4) + x1L5cff * lm15(n, S1, S2, S3, S4, S5) + + y1L4cff * lm14m1(n, S1, S2, S3, S4) + + y1L5cff * lm15m1(n, S1, S2, S3, S4, S5) ) # The selected approximations for nf = 3, 4, 5 if nf == 3: P3gqApp1 = ( P3GQ01 - + 3.4 * bfkl1 * (-(1 / (-1 + n) ** 2)) - - 161562.0 * 1 / ((-1 + n) * n) - + 36469.0 * 1 / n - + 72317.0 * (-(1 / n**2)) - - 3977.3 * lm12(n, S1, S2) - + 484.4 * lm13(n, S1, S2, S3) + + 6.0 * bfkl1 * (-(1 / (-1 + n) ** 2)) + - 744384.0 * 1 / ((-1 + n) * n) + + 2453640.0 * 1 / n + - 1540404.0 * (2 / (1 + n) + 1 / (2 + n)) + + 1933026.0 * -1 / n**2 + + 1142069.0 * 2 / n**3 + + 162196.0 * -6 / n**4 + - 2172.1 * lm13(n, S1, S2, S3) + - 93264.1 * lm12(n, S1, S2) + - 786973.0 * lm11(n, S1) + + 875383.0 * lm12m1(n, S1, S2) ) P3gqApp2 = ( P3GQ01 - + 5.4 * bfkl1 * (-(1 / (-1 + n) ** 2)) - - 546482.0 * 1 / ((-1 + n) * n) - - 39464.0 * 1 / n - - 401000.0 * (-(1 / n**2)) - + 13270.0 * lm12(n, S1, S2) - + 3289.0 * lm13(n, S1, S2, S3) + + 3.0 * bfkl1 * (-(1 / (-1 + n) ** 2)) + + 142414.0 * 1 / ((-1 + n) * n) + - 326525.0 * 1 / n + + 2159787.0 * ((3 + n) / (2 + 3 * n + n**2)) + - 289064.0 * -1 / n**2 + - 176358.0 * 2 / n**3 + + 156541.0 * -6 / n**4 + + 9016.5 * lm13(n, S1, S2, S3) + + 136063.0 * lm12(n, S1, S2) + + 829482.0 * lm11(n, S1) + - 2359050.0 * (S1 - n * (zeta2 - S2)) / n**2 ) elif nf == 4: P3gqApp1 = ( P3GQ01 - + 3.4 * bfkl1 * (-(1 / (-1 + n) ** 2)) - - 158805.0 * 1 / ((-1 + n) * n) - + 35098.0 * 1 / n - + 87258.0 * (-(1 / n**2)) - - 4834.1 * lm12(n, S1, S2) - + 176.6 * lm13(n, S1, S2, S3) + + 6.0 * bfkl1 * (-(1 / (-1 + n) ** 2)) + - 743535.0 * 1 / ((-1 + n) * n) + + 2125286.0 * 1 / n + - 1332472.0 * (2 / (1 + n) + 1 / (2 + n)) + + 1631173.0 * -1 / n**2 + + 1015255.0 * 2 / n**3 + + 142612.0 * -6 / n**4 + - 1910.4 * lm13(n, S1, S2, S3) + - 80851.0 * lm12(n, S1, S2) + - 680219.0 * lm11(n, S1) + + 752733.0 * lm12m1(n, S1, S2) ) P3gqApp2 = ( P3GQ01 - + 5.4 * bfkl1 * (-(1 / (-1 + n) ** 2)) - - 547215.0 * 1 / ((-1 + n) * n) - - 41523.0 * 1 / n - - 390350.0 * (-(1 / n**2)) - + 12571.0 * lm12(n, S1, S2) - + 3007.0 * lm13(n, S1, S2, S3) + + 3.0 * bfkl1 * (-(1 / (-1 + n) ** 2)) + + 160568.0 * 1 / ((-1 + n) * n) + - 361207.0 * 1 / n + + 2048948.0 * ((3 + n) / (2 + 3 * n + n**2)) + - 245963.0 * -1 / n**2 + - 171312.0 * 2 / n**3 + + 163099.0 * -6 / n**4 + + 8132.2 * lm13(n, S1, S2, S3) + + 124425.0 * lm12(n, S1, S2) + + 762435.0 * lm11(n, S1) + - 2193335.0 * (S1 - n * (zeta2 - S2)) / n**2 ) elif nf == 5: P3gqApp1 = ( P3GQ01 - + 3.4 * bfkl1 * (-(1 / (-1 + n) ** 2)) - - 154336.0 * 1 / ((-1 + n) * n) - + 33889.0 * 1 / n - + 103440.0 * (-(1 / n**2)) - - 5745.8 * lm12(n, S1, S2) - - 128.6 * lm13(n, S1, S2, S3) + + 6.0 * bfkl1 * (-(1 / (-1 + n) ** 2)) + - 785864.0 * 1 / ((-1 + n) * n) + + 285034.0 * 1 / n + - 131648.0 * (2 / (1 + n) + 1 / (2 + n)) + - 162840.0 * -1 / n**2 + + 321220.0 * 2 / n**3 + + 12688.0 * -6 / n**4 + + 1423.4 * lm13(n, S1, S2, S3) + + 1278.9 * lm12(n, S1, S2) + - 30919.9 * lm11(n, S1) + + 47588.0 * lm12m1(n, S1, S2) ) P3gqApp2 = ( P3GQ01 - + 5.4 * bfkl1 * (-(1 / (-1 + n) ** 2)) - - 546236.0 * 1 / ((-1 + n) * n) - - 43421.0 * 1 / n - - 378460.0 * (-(1 / n**2)) - + 11816.0 * lm12(n, S1, S2) - + 2727.3 * lm13(n, S1, S2, S3) + + 3.0 * bfkl1 * (-(1 / (-1 + n) ** 2)) + + 177094.0 * 1 / ((-1 + n) * n) + - 470694.0 * 1 / n + + 1348823.0 * ((3 + n) / (2 + 3 * n + n**2)) + - 52985.0 * -1 / n**2 + - 87354.0 * 2 / n**3 + + 176885.0 * -6 / n**4 + + 4748.8 * lm13(n, S1, S2, S3) + + 65811.9 * lm12(n, S1, S2) + + 396390.0 * lm11(n, S1) + - 1190212.0 * (S1 - n * (zeta2 - S2)) / n**2 ) else: raise NotImplementedError("nf=6 is not available at N3LO") diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsm.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsm.py index 5d80c9c75..30280b015 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsm.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsm.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{ns,-}^{(3)}`.""" + import numba as nb from eko.constants import CF, zeta3 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsp.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsp.py index de69d5313..6da3354f9 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsp.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsp.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{ns,+}^{(3)}`.""" + import numba as nb from eko.constants import CF, zeta3 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsv.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsv.py index 9b7dcfecd..b871dedad 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsv.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gnsv.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{ns,v}^{(3)}`.""" + import numba as nb from ......harmonics import cache as c diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gps.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gps.py index 87a8ba15d..13ca9d32b 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gps.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gps.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{ps}^{(3)}`.""" + import numba as nb from ......harmonics import cache as c diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gqg.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gqg.py index dd3244fd7..5d7a7b4fa 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gqg.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/fhmruvv/gqg.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{qg}^{(3)}`.""" + import numba as nb import numpy as np diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py index b5b7eadbc..2fa0f725d 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py @@ -19,6 +19,7 @@ lm14m1, lm14m2, lm15, + lm15m1, ) @@ -94,49 +95,37 @@ def gamma_gq_nf0(n, cache, variation): S5 = c.get(c.S5, cache, n) common = -22156.31283903764/np.power(-1. + n,4) + 95032.88047770769/np.power(-1. + n,3) - 37609.87654320987/np.power(n,7) - 35065.67901234568/np.power(n,6) - 175454.58483973087/np.power(n,5) - 375.3983146907502*lm14(n,S1,S2,S3,S4) - 13.443072702331962*lm15(n,S1,S2,S3,S4,S5) if variation == 1: - fit = -135325.37409909506/np.power(-1. + n,2) + 107389.69725534944/(-1. + n) - 281247.1594541515/(1. + n) + 145447.60744097419/(2. + n) - 1644.0474725539857*lm13(n,S1,S2,S3) + fit = -190798.78984643394/np.power(-1. + n,2) + 221131.0253655226/(-1. + n) + 648439.242059473/np.power(n,4) - 366347.6184986734/np.power(n,3) - 618607.6917836913/(1. + n) + 429310.45853894716/(2. + n) - 14371.95584746726*lm12(n,S1,S2) - 3733.573405767123*lm13(n,S1,S2,S3) - 2532.2371762381217*lm14m1(n,S1,S2,S3,S4) - 2065.2033221184793*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 2: - fit = -130157.18895885911/np.power(-1. + n,2) + 93282.05706699888/(-1. + n) - 169738.63893980338/(1. + n) + 9212.769374520116*lm12(n,S1,S2) - 223.51479074632925*lm13(n,S1,S2,S3) + fit = -181955.90739273484/np.power(-1. + n,2) + 174079.00572878437/(-1. + n) + 614415.2112591498/np.power(n,4) - 247925.1030423719/np.power(n,3) - 857285.692084171/(1. + n) - 465757.33455764863*lm11(n,S1) - 96058.685995113*lm12(n,S1,S2) - 8155.798140311963*lm13(n,S1,S2,S3) - 28516.09724542403*lm14m1(n,S1,S2,S3,S4) - 954.4182897594625*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 3: - fit = -130767.27520270286/np.power(-1. + n,2) + 94891.36609978844/(-1. + n) - 212410.3233945088/(1. + n) - 32955.07417912945*lm11(n,S1) - 1046.7526219200904*lm13(n,S1,S2,S3) + fit = 1.3256764418997709e6*(1/(-1. + n) - 1./n) - 274084.8755098396/np.power(-1. + n,2) - 562456.7287892306/(-1. + n) + 33100.78620012983/np.power(n,4) - 757963.2228636674/np.power(n,3) + 561634.5180237194/(1. + n) - 10366.577512205613*lm12(n,S1,S2) - 3308.849780595093*lm13(n,S1,S2,S3) + 3594.429612523227*lm14m1(n,S1,S2,S3,S4) - 164.77740102923354*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 4: - fit = -158783.450560317/np.power(-1. + n,2) + 90100.75345693348/(-1. + n) + 412018.22879229486/np.power(n,4) - 129027.27855213353/(1. + n) - 1753.8825871656047*lm13(n,S1,S2,S3) + fit = -407971.0442601025/np.power(-1. + n,2) + 1.6779394404324158e6/(-1. + n) - 1.8508191192624622e6/np.power(n,4) + 556695.4184628404/np.power(n,3) - 2.9603580600296143e6/np.power(n,2) - 1.6991648126491427e6/(1. + n) - 7644.442002706872*lm12(n,S1,S2) - 3016.5770039806234*lm13(n,S1,S2,S3) + 7449.550615450056*lm14m1(n,S1,S2,S3,S4) + 1121.5452001019141*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 5: - fit = -129693.48645695807/np.power(-1. + n,2) + 52876.75483885584/(-1. + n) + 158964.13837584556/np.power(n,3) - 85916.6315255873/(1. + n) - 1690.6720701417717*lm13(n,S1,S2,S3) + fit = -200706.92458750593/np.power(-1. + n,2) + 285544.01297554397/(-1. + n) + 598975.4725951094/np.power(n,4) - 459467.2186763565/np.power(n,3) - 125035.7898269595/(1. + n) - (469579.8213276177*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) - 19934.92974689708*lm12(n,S1,S2) - 4197.138060641495*lm13(n,S1,S2,S3) - 14354.398949387967*lm14m1(n,S1,S2,S3,S4) - 2780.1172673234187*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 6: - fit = -301210.2328458577/np.power(-1. + n,2) + 811215.7479286905/(-1. + n) - 1.242177631711221e6/np.power(n,2) - 857543.1305664484/(1. + n) - 1833.163010136661*lm13(n,S1,S2,S3) + fit = -213717.81278326/np.power(-1. + n,2) + 343080.67540216126/(-1. + n) + 736622.8254565693/np.power(n,4) - 673275.6329706735/np.power(n,3) + 1.541999929424894e6/(2. + n) + 1.2071530957537233e6*lm11(n,S1) + 197344.29014401618*lm12(n,S1,S2) + 7727.9806356929*lm13(n,S1,S2,S3) + 64812.92407405157*lm14m1(n,S1,S2,S3,S4) - 4944.138652016546*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 7: - fit = -122290.16043542989/np.power(-1. + n,2) + 71807.36048618097/(-1. + n) - 221400.82937350916/(2. + n) + 23236.477404056477*lm12(n,S1,S2) + 1938.8247584430924*lm13(n,S1,S2,S3) + fit = 694835.0487113381*(1/(-1. + n) - 1./n) - 234452.04501713923/np.power(-1. + n,2) - 189575.70173963293/(-1. + n) + 325918.06883470225/np.power(n,4) - 571607.5497870556/np.power(n,3) + 204293.30045438773/(2. + n) - 12272.59203346936*lm12(n,S1,S2) - 3510.9603747819533*lm13(n,S1,S2,S3) + 678.9706859669171*lm14m1(n,S1,S2,S3,S4) - 1069.1212905556267*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 8: - fit = -116702.31643837337/np.power(-1. + n,2) + 56325.17516760884/(-1. + n) - 448808.73529422894/(2. + n) - 134644.78516249143*lm11(n,S1) + 796.324422989612*lm13(n,S1,S2,S3) + fit = -66469.9146192077/np.power(-1. + n,2) - 612876.780153988/(-1. + n) + 2.0792390245041656e6/np.power(n,4) - 894780.384449624/np.power(n,3) + 1.6947745654652142e6/np.power(n,2) + 675086.4242602822/(2. + n) - 18223.392584809953*lm12(n,S1,S2) - 4144.046942562251*lm13(n,S1,S2,S3) - 8246.712776279062*lm14m1(n,S1,S2,S3,S4) - 3889.585992793313*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 9: - fit = -178667.39573180894/np.power(-1. + n,2) + 75445.99644274621/(-1. + n) + 761260.3281816904/np.power(n,4) - 123286.8456395018/(2. + n) - 1846.982948588938*lm13(n,S1,S2,S3) + fit = -203216.93313632446/np.power(-1. + n,2) + 301861.63488653634/(-1. + n) + 586444.881228152/np.power(n,4) - 483057.01613457815/np.power(n,3) - 108756.54115142432/(2. + n) - (588537.6906760911*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) - 21344.18742499368*lm12(n,S1,S2) - 4314.571987943781*lm13(n,S1,S2,S3) - 17349.286017533777*lm14m1(n,S1,S2,S3,S4) - 2961.2246827676927*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 10: - fit = -127216.28629540099/np.power(-1. + n,2) + 28899.09790707029/(-1. + n) + 228884.9205878143/np.power(n,3) - 63975.501562926234/(2. + n) - 1711.180018456112*lm13(n,S1,S2,S3) + fit = 800949.5231631215*(1/(-1. + n) - 1./n) - 237618.5496992028/np.power(-1. + n,2) - 270922.4474641897/(-1. + n) + 263195.643205183/np.power(n,4) - 556080.8360498395/np.power(n,3) - 184355.25890888766*lm11(n,S1) - 44285.07913209169*lm12(n,S1,S2) - 5227.3604731573405*lm13(n,S1,S2,S3) - 9115.503485867332*lm14m1(n,S1,S2,S3,S4) - 477.33174654807533*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 11: - fit = -54369.324330163065/np.power(-1. + n,2) - 236095.39968148115/(-1. + n) + 606214.4244773745/np.power(n,2) + 216429.75635890095/(2. + n) - 1551.7542579210171*lm13(n,S1,S2,S3) + fit = 48195.59002112752/np.power(-1. + n,2) - 1.3573040106844993e6/(-1. + n) + 3.124766843285419e6/np.power(n,4) - 1.067271569502171e6/np.power(n,3) + 3.014536621053924e6/np.power(n,2) - 940039.2873520318*lm11(n,S1) - 186091.1587357063*lm12(n,S1,S2) - 13389.081966931277*lm13(n,S1,S2,S3) - 65140.019870429314*lm14m1(n,S1,S2,S3,S4) - 3068.3813511505823*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 12: - fit = -127730.39915689365/np.power(-1. + n,2) + 86880.5772952685/(-1. + n) + 131088.0859004977*lm11(n,S1) + 45859.153375434624*lm12(n,S1,S2) + 3051.145461650118*lm13(n,S1,S2,S3) + fit = -203908.76301521514/np.power(-1. + n,2) + 304577.27308896056/(-1. + n) + 596339.0394012802/np.power(n,4) - 495589.18522419676/np.power(n,3) - (549763.1754595829*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) + 79530.6860231015*lm11(n,S1) - 6936.368263841917*lm12(n,S1,S2) - 3521.174399244307*lm13(n,S1,S2,S3) - 11936.20686787835*lm14m1(n,S1,S2,S3,S4) - 3091.865040882635*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 13: - fit = -249509.19871481528/np.power(-1. + n,2) + 80018.18821849066/(-1. + n) + 1.7178353341095438e6/np.power(n,4) - 29198.20288498338*lm12(n,S1,S2) - 6604.105966476303*lm13(n,S1,S2,S3) + fit = 996347.6558814617*(1/(-1. + n) - 1./n) - 307345.22952632234/np.power(-1. + n,2) - 5890.838164024106/(-1. + n) - 434907.89075372514/np.power(n,4) - 431371.6979604753/np.power(n,3) - 735420.6920727129/np.power(n,2) - 9690.333769848923*lm12(n,S1,S2) - 3236.2421958663294*lm13(n,S1,S2,S3) + 4552.132557305155*lm14m1(n,S1,S2,S3,S4) + 154.77587205927955*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 14: - fit = -129218.19651555142/np.power(-1. + n,2) + 11461.766456848798/(-1. + n) + 321900.6239594061/np.power(n,3) - 9442.986825272894*lm12(n,S1,S2) - 3194.4920722194884*lm13(n,S1,S2,S3) + fit = 241392.41481428457*(1/(-1. + n) - 1./n) - 214068.31142011366/np.power(-1. + n,2) + 131131.54358220598/(-1. + n) + 495935.3419568636/np.power(n,4) - 513820.30789226515/np.power(n,3) - (384073.9851893155*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) - 18192.626596597966*lm12(n,S1,S2) - 4035.389453017769*lm13(n,S1,S2,S3) - 11086.094113028495*lm14m1(n,S1,S2,S3,S4) - 2303.8893574584527*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 15: - fit = -87944.16009766924/np.power(-1. + n,2) - 83891.96406756257/(-1. + n) + 306548.65313472337/np.power(n,2) + 11486.326691371696*lm12(n,S1,S2) + 173.71945424342616*lm13(n,S1,S2,S3) - elif variation == 16: - fit = -202135.7995740037/np.power(-1. + n,2) + 82687.73905965324/(-1. + n) + 1.0495769899938635e6/np.power(n,4) + 50994.82207509583*lm11(n,S1) - 2848.098505650866*lm13(n,S1,S2,S3) - elif variation == 17: - fit = -128964.1511783234/np.power(-1. + n,2) + 24339.728042797506/(-1. + n) + 266935.24034010764/np.power(n,3) + 22383.637660612447*lm11(n,S1) - 2128.032930969243*lm13(n,S1,S2,S3) - elif variation == 18: - fit = -74648.83981878728/np.power(-1. + n,2) - 140958.82150230306/(-1. + n) + 408987.65266967454/np.power(n,2) - 43805.55005962004*lm11(n,S1) - 787.8265790554562*lm13(n,S1,S2,S3) - elif variation == 19: - fit = -71719.13674652952/np.power(-1. + n,2) - 21308.180757420447/(-1. + n) - 821124.7287279929/np.power(n,4) + 475769.01709201955/np.power(n,3) - 1564.6977442093062*lm13(n,S1,S2,S3) - elif variation == 20: - fit = -133558.27521182265/np.power(-1. + n,2) - 37615.76088185934/(-1. + n) + 484990.68454355566/np.power(n,4) + 220001.80072250665/np.power(n,2) - 1739.8412493001551*lm13(n,S1,S2,S3) - elif variation == 21: - fit = -110595.9812283641/np.power(-1. + n,2) - 31560.381420415717/(-1. + n) + 176663.97543390834/np.power(n,3) + 138310.07359867013/np.power(n,2) - 1674.8064387740321*lm13(n,S1,S2,S3) + fit = -184243.57777612918/np.power(-1. + n,2) + 174943.63966707757/(-1. + n) + 793566.8946787679/np.power(n,4) - 540182.7805370308/np.power(n,3) + 235146.35888011672/np.power(n,2) - (506879.3651168012*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) - 20911.184664809738*lm12(n,S1,S2) - 4290.912089188934*lm13(n,S1,S2,S3) - 16086.324716319741*lm14m1(n,S1,S2,S3,S4) - 3090.0331415667697*lm15m1(n,S1,S2,S3,S4,S5) else: - fit = -138152.69664751078/np.power(-1. + n,2) + 57913.880829154245/(-1. + n) + 171645.5636615693/np.power(n,4) + 77577.04360900483/np.power(n,3) + 20851.665375796576/np.power(n,2) - 82661.10297298252/(1. + n) - 23599.740384299566/(2. + n) - 330.42208404928425*lm11(n,S1) + 2435.882720720316*lm12(n,S1,S2) - 1327.8017698551957*lm13(n,S1,S2,S3) + fit = -204824.20590456025/np.power(-1. + n,2) + 311630.8552402414/(-1. + n) + 574082.1509765851/np.power(n,4) - 500136.3136750759/np.power(n,3) + 83245.25288646184/np.power(n,2) + 3414.410110455348/n - 182563.96455468299/(1. + n) + 182795.5714351391/(2. + n) - (166588.9358512939*S1)/np.power(n,2) - (166588.9358512939*S2)/n - 20231.20660278288*lm11(n,S1) - 19265.281611102873*lm12(n,S1,S2) - 4023.5797092198227*lm13(n,S1,S2,S3) - 6884.991578205952*lm14m1(n,S1,S2,S3,S4) - 1972.251097587273*lm15m1(n,S1,S2,S3,S4,S5) return common + fit @@ -166,49 +155,37 @@ def gamma_gq_nf1(n, cache, variation): S5 = c.get(c.S5, cache, n) common = 885.6738165500071/np.power(-1. + n,3) + 5309.62962962963/np.power(n,7) + 221.23456790123456/np.power(n,6) + 9092.91243376357/np.power(n,5) + 34.49474165523548*lm14(n,S1,S2,S3,S4) + 0.5486968449931413*lm15(n,S1,S2,S3,S4,S5) if variation == 1: - fit = -4154.154695948995/np.power(-1. + n,2) + 10568.669617295407/(-1. + n) - 17488.846844461823/(1. + n) + 12359.004664911017/(2. + n) + 211.10404507107253*lm13(n,S1,S2,S3) + fit = -4641.830354006266/np.power(-1. + n,2) + 9330.495800110972/(-1. + n) + 14344.09051426101/np.power(n,4) - 1016.4529739723794/np.power(n,3) - 6064.923487611063/(1. + n) - 2205.7352403247382/(2. + n) + 1484.8541015131434*lm12(n,S1,S2) + 431.5031264078472*lm13(n,S1,S2,S3) - 856.5578620911533*lm14m1(n,S1,S2,S3,S4) + 6.61766368570454*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 2: - fit = -3715.00258213197/np.power(-1. + n,2) + 9369.912250526479/(-1. + n) - 8013.721406089578/(1. + n) + 782.8293753310119*lm12(n,S1,S2) + 331.8098466308406*lm13(n,S1,S2,S3) + fit = -4687.263677692064/np.power(-1. + n,2) + 9572.241701801757/(-1. + n) + 14518.90006807081/np.power(n,4) - 1624.8890269149388/np.power(n,3) - 4838.624644014499/(1. + n) + 2392.997784211616*lm11(n,S1) + 1904.549512246748*lm12(n,S1,S2) + 454.2239274477203*lm13(n,S1,S2,S3) - 723.0562074580255*lm14m1(n,S1,S2,S3,S4) + 0.9106508564231698*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 3: - fit = -3766.8429586516354/np.power(-1. + n,2) + 9506.658795852165/(-1. + n) - 11639.62874491426/(1. + n) - 2800.265488570204*lm11(n,S1) + 261.8575086390502*lm13(n,S1,S2,S3) + fit = -6811.138044272443*(1/(-1. + n) - 1./n) - 4213.918161962191/np.power(-1. + n,2) + 13356.458528865467/(-1. + n) + 17505.612074825083/np.power(n,4) + 995.6134783259232/np.power(n,3) - 12128.839771112724/(1. + n) + 1464.2750761708346*lm12(n,S1,S2) + 429.3209612041876*lm13(n,S1,S2,S3) - 888.0357673648941*lm14m1(n,S1,S2,S3,S4) - 3.1464374221968265*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 4: - fit = -6147.4392986647545/np.power(-1. + n,2) + 9099.589851629416/(-1. + n) + 35010.09952148762/np.power(n,4) - 4554.387135843054/(1. + n) + 201.7711126307286*lm13(n,S1,S2,S3) + fit = -3526.0317032445505/np.power(-1. + n,2) + 1845.6312169595117/(-1. + n) + 27184.909343823376/np.power(n,4) - 5758.912493427602/np.power(n,3) + 15209.879770634008/np.power(n,2) - 513.1837033827802/(1. + n) + 1450.2890806227542*lm12(n,S1,S2) + 427.8192994247673*lm13(n,S1,S2,S3) - 907.8428666449199*lm14m1(n,S1,S2,S3,S4) - 9.755401357842457*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 5: - fit = -3675.6007556945196/np.power(-1. + n,2) + 5936.584418528788/(-1. + n) + 13507.53417196719/np.power(n,3) - 891.1801771144223/(1. + n) + 207.1422499668006*lm13(n,S1,S2,S3) + fit = -4590.923684246688/np.power(-1. + n,2) + 8999.550617808409/(-1. + n) + 14598.227915093874/np.power(n,4) - 538.0166438967607/np.power(n,3) - 8600.824838080449/(1. + n) + (2412.6347931026244*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) + 1513.4359164894108*lm12(n,S1,S2) + 433.88486067694004*lm13(n,S1,S2,S3) - 795.8172214607993*lm14m1(n,S1,S2,S3,S4) + 10.290808757929303*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 6: - fit = -18249.757773649242/np.power(-1. + n,2) + 70374.32470231941/(-1. + n) - 105550.57876215602/np.power(n,2) - 66457.98920891003/(1. + n) + 195.03447986946037*lm13(n,S1,S2,S3) + fit = -4866.531418583069/np.power(-1. + n,2) + 10526.106107096773/(-1. + n) + 15208.65298881981/np.power(n,4) - 4025.6149294747884/np.power(n,3) + 8703.225799886446/(2. + n) + 11835.100931020013*lm11(n,S1) + 3560.5504964992174*lm12(n,S1,S2) + 543.8738525149046*lm13(n,S1,S2,S3) - 196.29613565392873*lm14m1(n,S1,S2,S3,S4) - 21.60775819888546*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 7: - fit = -3343.5834681677507/np.power(-1. + n,2) + 8356.04624598052/(-1. + n) - 10452.80306687096/(2. + n) + 1444.9183960217892*lm12(n,S1,S2) + 433.89848620522463*lm13(n,S1,S2,S3) + fit = 6812.267406043017*(1/(-1. + n) - 1./n) - 5069.813407366513/np.power(-1. + n,2) + 5303.865079802739/(-1. + n) + 11182.04418020281/np.power(n,4) - 3028.851822020746/np.power(n,3) - 4411.837835317581/(2. + n) + 1505.436594939228*lm12(n,S1,S2) + 433.68565968275493*lm13(n,S1,S2,S3) - 825.0746801155074*lm14m1(n,S1,S2,S3,S4) + 16.38340848554099*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 8: - fit = -2996.1134775555597/np.power(-1. + n,2) + 7393.314503624469/(-1. + n) - 24593.753132227568/(2. + n) - 8372.642876397704*lm11(n,S1) + 362.8541655256052*lm13(n,S1,S2,S3) + fit = -3422.891059017386/np.power(-1. + n,2) + 1153.755670292513/(-1. + n) + 28371.871488638357/np.power(n,4) - 6197.289757168041/np.power(n,3) + 16615.82978575513/np.power(n,2) + 203.89110614955672/(2. + n) + 1447.093994233797*lm12(n,S1,S2) + 427.47877749637*lm13(n,S1,S2,S3) - 912.583492582551*lm14m1(n,S1,S2,S3,S4) - 11.268877794713138*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 9: - fit = -6849.300061096075/np.power(-1. + n,2) + 8582.308253713018/(-1. + n) + 47337.59912160785/np.power(n,4) - 4351.762124258069/(2. + n) + 198.4848688754035*lm13(n,S1,S2,S3) + fit = -4763.579488071934/np.power(-1. + n,2) + 10121.98975419346/(-1. + n) + 13736.287660471797/np.power(n,4) - 2160.6868401419974/np.power(n,3) - 7481.025709471715/(2. + n) - (5770.109793538375*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) + 1416.4974055579276*lm12(n,S1,S2) + 425.80694052284747*lm13(n,S1,S2,S3) - 1001.8262888413067*lm14m1(n,S1,S2,S3,S4) - 2.1670232041395643*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 10: - fit = -3649.905711097048/np.power(-1. + n,2) + 5687.873404469671/(-1. + n) + 14232.795555815104/np.power(n,3) - 663.5932741012635/(2. + n) + 206.92952890585326*lm13(n,S1,S2,S3) + fit = 4520.661520913708*(1/(-1. + n) - 1./n) - 5001.430874802961/np.power(-1. + n,2) + 7060.59716821144/(-1. + n) + 12536.572900553683/np.power(n,4) - 3364.161076731632/np.power(n,3) + 3981.2635172018045*lm11(n,S1) + 2196.7656407758154*lm12(n,S1,S2) + 470.75235872661165*lm13(n,S1,S2,S3) - 613.5570863075435*lm14m1(n,S1,S2,S3,S4) + 3.603350437056353*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 11: - fit = 879.9511001376588/np.power(-1. + n,2) - 10790.331004577562/(-1. + n) + 37696.34952104189/np.power(n,2) + 16772.9014435428/(2. + n) + 216.84313199599924*lm13(n,S1,S2,S3) + fit = -3388.259768452193/np.power(-1. + n,2) + 928.9237521114734/(-1. + n) + 28687.641066076383/np.power(n,4) - 6249.3846772154875/np.power(n,3) + 17014.423803619455/np.power(n,2) - 283.911571480371*lm11(n,S1) + 1396.3944319615423*lm12(n,S1,S2) + 424.6865855575389*lm13(n,S1,S2,S3) - 929.7664379765954*lm14m1(n,S1,S2,S3,S4) - 11.020846683201022*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 12: - fit = -3600.42868484152/np.power(-1. + n,2) + 9067.684803683303/(-1. + n) + 6188.946763244337*lm11(n,S1) + 2512.9829441244183*lm12(n,S1,S2) + 486.41350744844374*lm13(n,S1,S2,S3) + fit = -4811.168299020828/np.power(-1. + n,2) + 10308.789975744723/(-1. + n) + 14416.876062124396/np.power(n,4) - 3022.7356514174053/np.power(n,3) - (3102.930670591721*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) + 5470.669625759262*lm11(n,S1) + 2407.5666798018997*lm12(n,S1,S2) + 480.3823046452061*lm13(n,S1,S2,S3) - 629.4773212257594*lm14m1(n,S1,S2,S3,S4) - 11.153366255382775*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 13: - fit = -9349.864281360744/np.power(-1. + n,2) + 8743.696850292556/(-1. + n) + 81102.65214258479/np.power(n,4) - 1030.6341504008299*lm12(n,S1,S2) + 30.568594740114495*lm13(n,S1,S2,S3) + fit = 300.91468031027983*(1/(-1. + n) - 1./n) - 3495.6400189196065/np.power(-1. + n,2) + 1337.0787229077632/(-1. + n) + 27612.548291854742/np.power(n,4) - 6057.328428936091/np.power(n,3) + 15881.861322805855/np.power(n,2) + 1449.6712068638715*lm12(n,S1,S2) + 427.75295915863444*lm13(n,S1,S2,S3) - 908.7179226159642*lm14m1(n,S1,S2,S3,S4) - 10.04737351405501*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 14: - fit = -3670.6707559192682/np.power(-1. + n,2) + 5507.002671361118/(-1. + n) + 15197.611675043092/np.power(n,3) - 97.9484707672736*lm12(n,S1,S2) + 191.54370342235256*lm13(n,S1,S2,S3) + fit = 16604.63646140265*(1/(-1. + n) - 1./n) - 5510.0124055938695/np.power(-1. + n,2) - 1622.003211474526/(-1. + n) + 7510.417547162798/np.power(n,4) - 4276.8010810631495/np.power(n,3) + (8294.312330449271*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) + 1633.28339277492*lm12(n,S1,S2) + 445.0110299002262*lm13(n,S1,S2,S3) - 571.0008823762004*lm14m1(n,S1,S2,S3,S4) + 43.04899480027303*lm15m1(n,S1,S2,S3,S4,S5) elif variation == 15: - fit = -1722.0358945603757/np.power(-1. + n,2) + 1005.1506697978073/(-1. + n) + 14472.81254861761/np.power(n,2) + 890.1688417705905*lm12(n,S1,S2) + 350.5641184465057*lm13(n,S1,S2,S3) - elif variation == 16: - fit = -7677.684552786546/np.power(-1. + n,2) + 8837.926288795223/(-1. + n) + 57514.561003940005/np.power(n,4) + 1800.00821732893*lm11(n,S1) + 163.14762960523643*lm13(n,S1,S2,S3) - elif variation == 17: - fit = -3668.0356413358095/np.power(-1. + n,2) + 5640.580814304368/(-1. + n) + 14627.476889260639/np.power(n,3) + 232.17686518512448*lm11(n,S1) + 202.60567395706914*lm13(n,S1,S2,S3) - elif variation == 18: - fit = -691.6734321623419/np.power(-1. + n,2) - 3417.4240793927916/(-1. + n) + 22411.6434750231/np.power(n,2) - 3394.848223236357*lm11(n,S1) + 276.04609873762405*lm13(n,S1,S2,S3) - elif variation == 19: - fit = -3074.255121846279/np.power(-1. + n,2) + 5167.092611529961/(-1. + n) - 8517.21102404984/np.power(n,4) + 16793.629342505785/np.power(n,3) + 208.44893320267045*lm13(n,S1,S2,S3) - elif variation == 20: - fit = -5257.044527918616/np.power(-1. + n,2) + 4591.469890746334/(-1. + n) + 37585.871230195466/np.power(n,4) + 7765.593309542773/np.power(n,2) + 202.2667418438865*lm13(n,S1,S2,S3) - elif variation == 21: - fit = -3477.5096784512552/np.power(-1. + n,2) + 5060.750476829951/(-1. + n) + 13691.12777479692/np.power(n,3) + 1434.6372023383353/np.power(n,2) + 207.3068180594*lm13(n,S1,S2,S3) + fit = -3458.461150841499/np.power(-1. + n,2) + 1391.69402227194/(-1. + n) + 27983.56958776381/np.power(n,4) - 6090.191530645382/np.power(n,3) + 16174.989824710121/np.power(n,2) - (153.08676471398127*(S1 - 1.*n*(1.6449340668482262 - 1.*S2)))/np.power(n,2) + 1446.2823060910362*lm12(n,S1,S2) + 427.43442970735236*lm13(n,S1,S2,S3) - 914.9511127677407*lm14m1(n,S1,S2,S3,S4) - 11.027364975586181*lm15m1(n,S1,S2,S3,S4,S5) else: - fit = -4659.8548692239365/np.power(-1. + n,2) + 8775.661049395696/(-1. + n) + 11906.360571226945/np.power(n,4) + 4192.865495685177/np.power(n,3) - 1036.6448907424908/np.power(n,2) - 5192.654929396816/(1. + n) - 520.4764518573357/(2. + n) - 302.22022583075585*lm11(n,S1) + 214.3960445752241*lm12(n,S1,S2) + 245.07815446568293*lm13(n,S1,S2,S3) + fit = -4363.18369812144/np.power(-1. + n,2) + 7402.8344620734415/(-1. + n) + 18359.88144598285/np.power(n,4) - 3494.380230313365/np.power(n,3) + 5393.1323005016375/np.power(n,2) - 1612.81199529589/n - 2143.0930962801012/(1. + n) - 346.09879193853544/(2. + n) + (112.05465964718788*S1)/np.power(n,2) + (112.05465964718788*S2)/n + 1559.7413524474882*lm11(n,S1) + 1751.7963891028098*lm12(n,S1,S2) + 445.5744715382606*lm13(n,S1,S2,S3) - 778.3040856988591*lm14m1(n,S1,S2,S3,S4) - 0.6893048255383367*lm15m1(n,S1,S2,S3,S4,S5) return common + fit diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py index 14886c5ab..4bd7fa472 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{ns,-}^{(3)}`.""" + import numba as nb from eko.constants import CF, zeta3 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py index c8a75e081..e6364f9d4 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{ns,+}^{(3)}`.""" + import numba as nb from .....harmonics import cache as c diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py index 9de2d2f7f..b8dc60ec2 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py @@ -1,4 +1,5 @@ r"""The unpolarized, space-like anomalous dimension :math:`\gamma_{ns,v}^{(3)}`.""" + import numba as nb from .....harmonics import cache as c diff --git a/src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py index 267924c9b..e7a4ecd69 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py @@ -32,12 +32,14 @@ def gamma_ns(order, mode, n, nf): gamma_ns = np.zeros(order[0], np.complex_) gamma_ns[0] = as1.gamma_ns(n, cache) if order[0] >= 2: + gamma_ns_1 = 0.0 if mode == 10101: gamma_ns_1 = as2.gamma_nsp(n, nf, cache) elif mode in [10201, 10200]: gamma_ns_1 = as2.gamma_nsm(n, nf, cache) gamma_ns[1] = gamma_ns_1 if order[0] >= 3: + gamma_ns_2 = 0.0 if mode == 10101: gamma_ns_2 = as3.gamma_nsp(n, nf, cache) elif mode == 10201: diff --git a/src/ekore/anomalous_dimensions/unpolarized/time_like/as3.py b/src/ekore/anomalous_dimensions/unpolarized/time_like/as3.py index 70793acc1..0d05c215e 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/time_like/as3.py +++ b/src/ekore/anomalous_dimensions/unpolarized/time_like/as3.py @@ -265,7 +265,7 @@ def gamma_nsv(N, nf, cache): S11 = S1 + N1I S12 = S11 + N2I B1 = -S1 * NI - if abs(N.imag) < 0.00001 and abs(N.real) < 0.00001: + if abs(N.imag) < 0.00001 and abs(N.real - 1) < 0.00001: B1M = -zeta2 else: B1M = -S1M * NMI diff --git a/src/ekore/harmonics/__init__.py b/src/ekore/harmonics/__init__.py index d5818dacd..a6a69f5f0 100644 --- a/src/ekore/harmonics/__init__.py +++ b/src/ekore/harmonics/__init__.py @@ -2,6 +2,7 @@ Definitions are coming from :cite:`MuselliPhD,Bl_mlein_2000,Blumlein:2009ta`. """ + from . import cache, g_functions, polygamma from .w1 import S1, Sm1 from .w2 import S2, Sm2 diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index 1bc8f54fe..d1892ea1b 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -1,4 +1,5 @@ """Caching harmonic sums across :mod:`ekore`.""" + from typing import Optional import numba as nb diff --git a/src/ekore/harmonics/g_functions.py b/src/ekore/harmonics/g_functions.py index 6c648e95b..875238547 100644 --- a/src/ekore/harmonics/g_functions.py +++ b/src/ekore/harmonics/g_functions.py @@ -3,6 +3,7 @@ Implementations of some Mellin transformations :math:`g_k(N)` :cite:`MuselliPhD` appearing in the analytic continuation of harmonics sums of weight = 3,4. """ + import numba as nb import numpy as np diff --git a/src/ekore/harmonics/log_functions.py b/src/ekore/harmonics/log_functions.py index fe0d48c38..eccba40bf 100644 --- a/src/ekore/harmonics/log_functions.py +++ b/src/ekore/harmonics/log_functions.py @@ -6,6 +6,7 @@ - :math:`\ln^k(1-x), \quad k = 1,3,4,5` """ + import numba as nb diff --git a/src/ekore/harmonics/w3.py b/src/ekore/harmonics/w3.py index be245aa72..7bed3beee 100644 --- a/src/ekore/harmonics/w3.py +++ b/src/ekore/harmonics/w3.py @@ -69,8 +69,7 @@ def Sm3(N, hS3, hS3mh, hS3h, is_singlet=None): """ if is_singlet is None: return ( - 1 / 2**2 * ((1 - (-1) ** N) / 2 * hS3mh + ((-1) ** N + 1) / 2 * hS3h) - - hS3 + 1 / 2**2 * ((1 - (-1) ** N) / 2 * hS3mh + ((-1) ** N + 1) / 2 * hS3h) - hS3 ) if is_singlet: return 1 / 2**2 * hS3h - hS3 diff --git a/src/ekore/harmonics/w4.py b/src/ekore/harmonics/w4.py index 0b6863542..869e4c9bf 100644 --- a/src/ekore/harmonics/w4.py +++ b/src/ekore/harmonics/w4.py @@ -69,8 +69,7 @@ def Sm4(N, hS4, hS4mh, hS4h, is_singlet=None): """ if is_singlet is None: return ( - 1 / 2**3 * ((1 - (-1) ** N) / 2 * hS4mh + ((-1) ** N + 1) / 2 * hS4h) - - hS4 + 1 / 2**3 * ((1 - (-1) ** N) / 2 * hS4mh + ((-1) ** N + 1) / 2 * hS4h) - hS4 ) if is_singlet: return 1 / 2**3 * hS4h - hS4 diff --git a/src/ekore/harmonics/w5.py b/src/ekore/harmonics/w5.py index 19b52881c..169de46e8 100644 --- a/src/ekore/harmonics/w5.py +++ b/src/ekore/harmonics/w5.py @@ -68,8 +68,7 @@ def Sm5(N, hS5, hS5mh, hS5h, is_singlet=None): """ if is_singlet is None: return ( - 1 / 2**4 * ((1 - (-1) ** N) / 2 * hS5mh + ((-1) ** N + 1) / 2 * hS5h) - - hS5 + 1 / 2**4 * ((1 - (-1) ** N) / 2 * hS5mh + ((-1) ** N + 1) / 2 * hS5h) - hS5 ) if is_singlet: return 1 / 2**4 * hS5h - hS5 diff --git a/src/ekore/operator_matrix_elements/polarized/space_like/as1.py b/src/ekore/operator_matrix_elements/polarized/space_like/as1.py index 86aec2bb7..29d74b138 100644 --- a/src/ekore/operator_matrix_elements/polarized/space_like/as1.py +++ b/src/ekore/operator_matrix_elements/polarized/space_like/as1.py @@ -6,6 +6,7 @@ Additionally, a different convention for the anomalous dimensions is used, yielding a factor 2 in the |OME|'s wherever they are present. The anomalous dimensions and beta function with the addition 'hat' have the form :math:`\hat\gamma = \gamma^{(nf+1)} - \gamma^{(nf)}`. """ + import numba as nb import numpy as np diff --git a/src/ekore/operator_matrix_elements/polarized/space_like/as2.py b/src/ekore/operator_matrix_elements/polarized/space_like/as2.py index 86d061ddb..402274a0c 100644 --- a/src/ekore/operator_matrix_elements/polarized/space_like/as2.py +++ b/src/ekore/operator_matrix_elements/polarized/space_like/as2.py @@ -4,6 +4,7 @@ As in the |NLO| |OME|, in the paper, an additional factor 2 can be found in front of the anomalous dimensions and factor (-1) for odd powers of L. The anomalous dimensions and beta function with the addition 'hat' are defined as in the |NLO| case. """ + import numba as nb import numpy as np @@ -120,9 +121,7 @@ def A_hq_ps(n, cache, L, nf): ) # term that differentiates between M scheme and Larin scheme, # we are computing in M scheme hence the addition of this term - z_qq_ps = ( - -CF * TR * nf * ((8 * (2 + n) * (n**2 - n - 1)) / (n**3 * (n + 1) ** 3)) - ) + z_qq_ps = -CF * TR * nf * ((8 * (2 + n) * (n**2 - n - 1)) / (n**3 * (n + 1) ** 3)) gamma1_ps_qqhat = (16 * CF * (2 + n) * (1 + 2 * n + n**3) * TR) / ( n**3 * ((1 + n) ** 3) ) @@ -173,7 +172,7 @@ def A_hg(n, cache, L): -2 * CF * ( - 3 + 6 * ( 4 + 8 * n @@ -188,7 +187,7 @@ def A_hg(n, cache, L): * n**2 * (1 + n) ** 2 * (2 + n) - * (2 + 3 * n + 3 * n**3) + * (2 + 3 * n + 3 * n**2) * np.pi**2 + 12 * n**2 * (1 + n) ** 3 * (-36 - 22 * n - 2 * n**2 + n**3) * S1 + 12 * n**2 * (1 + n) ** 3 * (-2 + 3 * n + 3 * n**2) * S1**2 @@ -207,7 +206,6 @@ def A_hg(n, cache, L): + CA * ( -24 - * (1 + n) ** 3 * ( 4 + 12 * n @@ -220,17 +218,9 @@ def A_hg(n, cache, L): + 2 * n**8 ) + 8 * (-1 + n) * n**2 * (1 + n) ** 2 * (2 + n) ** 2 * np.pi**2 - + 24 - * n**3 - * (1 + n) - * (2 - 10 * n - n**2 + 4 * n**3 + n**4) - * S1 + + 24 * n**3 * (1 + n) * (2 - 10 * n - n**2 + 4 * n**3 + n**4) * S1 + 24 * n**3 * (1 + n) ** 2 * (5 + 4 * n + n**2) * S1**2 - + 24 - * n**2 - * (1 + n) ** 2 - * (-16 + 15 * n + 24 * n**2 + 7 * n**3) - * S2 + + 24 * n**2 * (1 + n) ** 2 * (-16 + 15 * n + 24 * n**2 + 7 * n**3) * S2 - 24 * (1 - n) * n**3 @@ -345,8 +335,7 @@ def A_gg(n, cache, L): S1 = c.get(c.S1, cache, n) ggg1_canf = ( -5 * S1 / 9 - + (-3 + 13 * n + 16 * n**2 + 6 * n**3 + 3 * n**4) - / (9 * n**2 * (1 + n) ** 2) + + (-3 + 13 * n + 16 * n**2 + 6 * n**3 + 3 * n**4) / (9 * n**2 * (1 + n) ** 2) ) * 4 ggg1_cfnf = (4 + 2 * n - 8 * n**2 + n**3 + 5 * n**4 + 3 * n**5 + n**6) / ( n**3 * (1 + n) ** 3 @@ -364,16 +353,7 @@ def A_gg(n, cache, L): - 8 ) / (n**4 * (1 + n) ** 4) a_gg_a = ( - 2 - * ( - 15 * n**6 - + 45 * n**5 - + 374 * n**4 - + 601 * n**3 - + 161 * n**2 - - 24 * n - + 36 - ) + 2 * (15 * n**6 + 45 * n**5 + 374 * n**4 + 601 * n**3 + 161 * n**2 - 24 * n + 36) ) / (27 * n**3 * (1 + n) ** 3) - (4 * S1 * (47 + 56 * n) / (27 * (1 + n))) a_gg_l0 = TR * (CF * a_gg_f + CA * a_gg_a) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py index de982d550..f1dd3d345 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py @@ -20,7 +20,7 @@ def A_singlet(matching_order, n, nf, L, is_msbar): nf: int number of active flavor below threshold L : float - :math:``\ln(\mu_F^2 / m_h^2)`` + :math:`\ln(\mu_F^2 / m_h^2)` is_msbar: bool add the |MSbar| contribution @@ -54,7 +54,7 @@ def A_non_singlet(matching_order, n, nf, L): nf: int number of active flavor below threshold L : float - :math:``\ln(\mu_F^2 / m_h^2)`` + :math:`\ln(\mu_F^2 / m_h^2)` Returns ------- diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py index 76eaecb7f..d776f23f1 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py @@ -5,6 +5,7 @@ The other matching conditions for the |VFNS| at :math:`\mu_F^2 \neq m_H^2` are provided in :cite:`Buza_1998`. """ + import numba as nb import numpy as np @@ -39,12 +40,7 @@ def A_hh(n, cache, L): S2m = c.get(c.S2, cache, n) - 1 / n**2 # harmonics.S2(n - 1) ahh_l = (2 + n - 3 * n**2) / (n * (1 + n)) + 4 * S1m ahh = 2 * ( - 2 - + 5 * n - + n**2 - - 6 * n**3 - - 2 * n**4 - - 2 * n * (-1 - 2 * n + n**3) * S1m + 2 + 5 * n + n**2 - 6 * n**3 - 2 * n**4 - 2 * n * (-1 - 2 * n + n**3) * S1m ) / (n * (1 + n)) ** 2 + 4 * (S1m**2 + S2m) return -CF * (ahh_l * L + ahh) @@ -70,9 +66,7 @@ def A_gh(n, L): """ agh_l1 = (2 + n + n**2) / (n * (n**2 - 1)) - agh_l0 = (-4 + 2 * n + n**2 * (15 + n * (3 + n - n**2))) / ( - n * (n**2 - 1) - ) ** 2 + agh_l0 = (-4 + 2 * n + n**2 * (15 + n * (3 + n - n**2))) / (n * (n**2 - 1)) ** 2 return 2 * CF * (agh_l0 + agh_l1 * L) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py index 7f5de669b..801837016 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py @@ -1,13 +1,14 @@ r"""The unpolarized, spacelike |NNLO| |OME|. See, :cite:`Buza_1998` appendix B. -The expession for :math:`\mu_F^2 = m_H^2` are taken from :cite:`Vogt:2004ns` directly in N space. +The expression for :math:`\mu_F^2 = m_H^2` are taken from :cite:`Vogt:2004ns` directly in N space. While the parts proportional to :math:`\ln(\mu_F^2 / m_h^2)` comes |QCDNUM| (https://github.com/N3PDF/external/blob/master/qcdnum/qcdnum/pij/ome.f) and Mellin transformed with Mathematica. -The expession for ``A_Hg_l0`` comes form :cite:`Bierenbaum:2009zt`. +The expression for ``A_Hg_l0`` comes form :cite:`Bierenbaum:2009zt`. """ + import numba as nb import numpy as np @@ -57,16 +58,11 @@ def A_qq_ns(n, cache, L): + 20.0 / 9.0 * (S2 - 1.0 / n**2 - zeta2 + S2 + 1.0 / (n + 1.0) ** 2 - zeta2) + 2.0 / 3.0 - * ( - -2.0 * (S3 - 1.0 / n**3 - zeta3) - - 2.0 * (S3 + 1.0 / (n + 1.0) ** 3 - zeta3) - ) + * (-2.0 * (S3 - 1.0 / n**3 - zeta3) - 2.0 * (S3 + 1.0 / (n + 1.0) ** 3 - zeta3)) ) a_qq_l1 = ( - 2 - * (-12 - 28 * n + 9 * n**2 + 34 * n**3 - 3 * n**4) - / (9 * (n * (n + 1)) ** 2) + 2 * (-12 - 28 * n + 9 * n**2 + 34 * n**3 - 3 * n**4) / (9 * (n * (n + 1)) ** 2) + 80 / 9 * S1m - 16 / 3 * S2m ) @@ -200,15 +196,7 @@ def A_hg(n, cache, L): + 12 * Sm3 * (2 + n + n**2) / (n * (1 + n) * (2 + n)) - 24 * Sm2 * (4 + n - n**2) / ((1 + n) * (2 + n)) ** 2 - S1 - * ( - 48 / n - + 432 - + 564 * n - + 324 * n**2 - + 138 * n**3 - + 48 * n**4 - + 6 * n**5 - ) + * (48 / n + 432 + 564 * n + 324 * n**2 + 138 * n**3 + 48 * n**4 + 6 * n**5) / ((1 + n) * (2 + n)) ** 3 + S1 * (-160 - 32 / n**2 - 80 / n + 8 * n * (n - 1)) @@ -219,19 +207,10 @@ def A_hg(n, cache, L): * S2 * (63 + 48 / n**2 + 54 / n + 39 * n + 63 * n**2 + 21 * n**3) / ((n - 1) * (1 + n) ** 2 * (2 + n) ** 2) - + 8 - * S2 - * (17 - 2 / n**2 - 5 / n + n * (17 + n)) - / (3 * (1 + n) ** 2 * (2 + n)) + + 8 * S2 * (17 - 2 / n**2 - 5 / n + n * (17 + n)) / (3 * (1 + n) ** 2 * (2 + n)) + (1 + 2 / n + n) / ((1 + n) * (2 + n)) - * ( - 24 * Sm2 * S1 - + 10 * S1**3 / 9 - + 46 * S1 * S2 / 3 - + 176 * S3 / 9 - - 24 * Sm21 - ) + * (24 * Sm2 * S1 + 10 * S1**3 / 9 + 46 * S1 * S2 / 3 + 176 * S3 / 9 - 24 * Sm21) ) a_hg_l1 = ( diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py index 10ddd6e38..b71d8a37e 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py @@ -57,8 +57,12 @@ - :cite:`Ablinger:2022wbb`. J. Ablinger, J. and A. Behring, J. Blümlein, A. De Freitas, C. Schneider, A. Goedicke, C. von Manteuffel and K. Schonwald. The Unpolarized and Polarized Single-Mass Three-Loop Heavy Flavor Operator - Matrix Elements $A_{gg,Q}$ and $\Delta A_{gg,Q}$}. - DESY 15-112, DO-TH 22/26, CERN-TH-2022-179, ZU-TH 53/22, RISC Report Series 22-25, MSUHEP-22-036 + Matrix Elements $A_{gg,Q}$ and $\Delta A_{gg,Q}$}. JHEP 12 (2022) 134, + doi:10.1007/JHEP12(2022)134, + - :cite:`Ablinger:2024xtt`. J. Ablinger, A. Behring, J. Blümlein, A. De + Freitas, A. von Manteuffel, C. Schneider, K. Schönwald. + The non-first-order-factorizable contributions to the three-loop single-mass + operator matrix elements $A_{Qg}^{(3)}$ and $\Delta A_{Qg}^{(3)}$. """ @@ -82,11 +86,11 @@ def A_singlet(n, cache, nf, L): A^{S,(3)} = \left(\begin{array}{cc} A_{gg, H}^{S,(3)} & A_{gq, H}^{S,(3)} & 0 \\ A_{qg, H}^{S,(3)} & A_{qq,H}^{NS,(3)} + A_{qq,H}^{PS,(3)} & 0\\ - A_{hg}^{S,(3)} & A_{hq}^{PS,(3)} & 0\\ + A_{Hg}^{S,(3)} & A_{Hq}^{PS,(3)} & 0\\ \end{array}\right) When using the code, please cite the complete list of references - available at the top of this module :mod:`ekore.matching_conditions.as3`. + available at the top of this module :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- @@ -102,7 +106,7 @@ def A_singlet(n, cache, nf, L): Returns ------- A_S : numpy.ndarray - |NNLO| singlet |OME| :math:`A^{S,(3)}(N)` + |N3LO| singlet |OME| :math:`A^{S,(3)}(N)` """ A_hq_3 = A_Hq(n, cache, nf, L) @@ -137,7 +141,7 @@ def A_ns(n, cache, nf, L): \end{array}\right) When using the code, please cite the complete list of references available - at the top of this module :mod:`ekore.matching_conditions.as3`. + at the top of this module :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py index fe5fab45a..317345fc6 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py @@ -1,4 +1,5 @@ """The unpolarized, space-like |N3LO| heavy-gluon |OME|.""" + # pylint: skip-file import numba as nb import numpy as np @@ -11,10 +12,10 @@ def A_Hg(n, cache, nf, L): r"""Compute the |N3LO| singlet |OME| :math:`A_{Hg}^{S,(3)}(N)`. - The expression is presented in :cite:`Bierenbaum:2009mv`. + The expression is presented in :cite:`Bierenbaum:2009mv,Blumlein:2017wxd,Ablinger:2024xtt`. When using the code, please cite the complete list of references - available in :mod:`ekore.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg_param.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg_param.py index 8791817b7..1d6dde4dd 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg_param.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg_param.py @@ -1,27 +1,29 @@ -"""The approximated incomplete part of renormalization constant :math:`a_{Hg}^{S,(3)}(N)`.""" +"""The approximated part of renormalization constant :math:`a_{Hg}^{(3)}(N)`.""" + # pylint: skip-file import numba as nb import numpy as np from .....harmonics import cache as c +from .....harmonics.log_functions import lm11, lm11m1, lm12, lm13, lm14, lm15 @nb.njit(cache=True) def a_Hg3(n, cache, nf): - r"""Compute the approximate incomplete part of :math:`a_{Hg}^{S,(3)}(N)`. + r"""Compute :math:`a_{Hg}^{(3)}(N)`. - This is composed by two different part: - 1. the known part proportional to :math:`T_{F}` and - presented in :cite:`Blumlein:2017wxd` :eqref:`3.1`. + This is composed by two parts: - 2. A parametrized part for the unknown factors, - which is constructed from the 5 lowest moments - presented in :cite:`Bierenbaum:2009mv` :eqref:`8.50-8.54` and the - |LL| small-x contribution from :math:`Kawamura:2012cr` :eqref:`3.47` + 1. the exact part proportional to :math:`n_f T_{F}` and presented in :cite:`Blumlein:2017wxd` :eqref:`3.1`. + 2. a parametrized expression for the :math:`n_f^0` piece + derived from: the 5 lowest moments, presented in + :cite:`Bierenbaum:2009mv` :eqref:`8.50-8.54`; + and the :math:`x \to 0,1` limits from :eqref:`4.4-4.5` + of :cite:`Ablinger:2024xtt`. The |LL| small-x contribution + was originally computed in :cite:`Kawamura:2012cr`, :eqref:`3.47`. The parametrized part has been tested to be in reasonable agreement - with the one provided in :math:`Kawamura:2012cr` :eqref:`3.49`, :eqref:`3.50`. - The :math:`n_f` part is exact. + with the one provided in :cite:`Kawamura:2012cr` :eqref:`3.49`, :eqref:`3.50`. Parameters ---------- @@ -35,7 +37,7 @@ def a_Hg3(n, cache, nf): Returns ------- complex - :math:`A_{Hg}^{S,(3)}(N)` + :math:`a_{Hg}^{(3)}(N)` """ S1 = c.get(c.S1, cache, n) @@ -52,921 +54,287 @@ def a_Hg3(n, cache, nf): Sm211 = c.get(c.Sm211, cache, n, is_singlet=True) Sm31 = c.get(c.Sm31, cache, n, is_singlet=True) Sm4 = c.get(c.Sm4, cache, n, is_singlet=True) - parametrized_part = ( - -(6649.4461758486095 / n**2) - + (-7592.941358147846 + 6307.239141492633 * n) / (-1.0 + n) ** 2 - + ( - -4874.067051829699 - - 834.8649717514339 * S1 - - 106.571000154652 * S1**2 - - 228.16722542830036 * S1**3 - ) - / n + S5 = c.get(c.S5, cache, n) + + Lm11 = lm11(n, S1) + Lm12 = lm12(n, S1, S2) + Lm13 = lm13(n, S1, S2, S3) + Lm14 = lm14(n, S1, S2, S3, S4) + Lm15 = lm15(n, S1, S2, S3, S4, S5) + Lm11m1 = lm11m1(n, S1) + + # parametrized nf^0 part + aHg_nf0 = ( + -(10505.541212 / (-1 + n) ** 2) + - 581.3333332799999 / n**6 + - 522.2222222400001 / n**5 + - 3084.5476332000003 / n**4 + - 1440.0967656 / n**3 + - 10739.21741 / n**2 + - 6890.392506169613 / n + + (8956.649545 * n) / (-1.0 + n) ** 2 + + 7861.809052567688 / (1 + n) ** 2 + - 795.4199930418246 / (n + n**2) + - 19687.320434140434 / (2 + 3 * n + n**2) + + 737.165347 * Lm11 + - 332.5368214 * Lm12 + + 4.380199906 * Lm13 + - 8.20987654 * Lm14 + + 3.703703704 * Lm15 + - 12429.982192922555 * Lm11m1 ) - return parametrized_part + ( - (-1.0684950250307503 * (2.0 + n + np.power(n, 2))) / (n * (1.0 + n) * (2.0 + n)) - + 1.3333333333333333 + + # exact nf^1 part + aHg_nf1 = ( + 1 + / (n**6 * (1 + n) ** 6 * (2 + n) ** 5) * ( - 0.25 + (1 / (-1 + n)) * ( - 1.6449340668482262 - * ( - ( - 0.2222222222222222 - * ( - 1728.0 - + 4992.0 * n - + 8944.0 * np.power(n, 2) - + 11680.0 * np.power(n, 3) - + 4444.0 * np.power(n, 4) - - 4900.0 * np.power(n, 5) - - 6377.0 * np.power(n, 6) - + 617.0 * np.power(n, 7) - + 6930.0 * np.power(n, 8) - + 6142.0 * np.power(n, 9) - + 2331.0 * np.power(n, 10) - + 333.0 * np.power(n, 11) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 4) - * np.power(1.0 + n, 4) - * np.power(2.0 + n, 3) - ) - + ( - 8.88888888888889 - * (6.0 + 11.0 * n + 4.0 * np.power(n, 2) + np.power(n, 3)) - * S1 - ) - / (np.power(n, 2) * (1.0 + n) * (2.0 + n)) - ) - + ( - 1.6449340668482262 - * (2.0 + n + np.power(n, 2)) - * (-13.333333333333334 * np.power(S1, 2) + 8.0 * S2) - ) - / (n * (1.0 + n) * (2.0 + n)) - + nf - * ( - ( - 0.00411522633744856 - * ( - -1.24416e6 - - 7.865856e6 * n - - 2.3256576e7 * np.power(n, 2) - - 4.2534912e7 * np.power(n, 3) - - 5.3947712e7 * np.power(n, 4) - - 5.5711424e7 * np.power(n, 5) - - 4.075048e7 * np.power(n, 6) - - 1.0343664e7 * np.power(n, 7) - + 1.264032e7 * np.power(n, 8) - + 1.1884298e7 * np.power(n, 9) - - 2.970289e6 * np.power(n, 10) - - 1.0465411e7 * np.power(n, 11) - - 5.568833e6 * np.power(n, 12) - + 575913.0 * np.power(n, 13) - + 1.874085e6 * np.power(n, 14) - + 879391.0 * np.power(n, 15) - + 186525.0 * np.power(n, 16) - + 15777.0 * np.power(n, 17) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 6) - * np.power(1.0 + n, 6) - * np.power(2.0 + n, 5) - ) - - ( - 0.3950617283950617 - * ( - 141.0 - + 521.0 * n - + 789.0 * np.power(n, 2) - + 185.0 * np.power(n, 3) - + 10.0 * np.power(n, 4) - ) - * np.power(S1, 2) - ) - / (np.power(n, 2) * np.power(1.0 + n, 2) * (2.0 + n)) - + ( - 0.3950617283950617 - * ( - 24.0 - + 83.0 * n - + 49.0 * np.power(n, 2) - + 10.0 * np.power(n, 3) - ) - * np.power(S1, 3) - ) - / (np.power(n, 2) * (1.0 + n) * (2.0 + n)) - + 1.6449340668482262 - * ( - ( - 0.2222222222222222 - * (-2.0 + n) - * ( - 864.0 - + 3264.0 * n - + 6232.0 * np.power(n, 2) - + 9804.0 * np.power(n, 3) - + 10888.0 * np.power(n, 4) - + 9325.0 * np.power(n, 5) - + 6717.0 * np.power(n, 6) - + 3842.0 * np.power(n, 7) - + 1606.0 * np.power(n, 8) - + 405.0 * np.power(n, 9) - + 45.0 * np.power(n, 10) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 4) - * np.power(1.0 + n, 4) - * np.power(2.0 + n, 3) - ) - + ( - 1.7777777777777777 - * ( - 12.0 - + 28.0 * n - + 11.0 * np.power(n, 2) - + 5.0 * np.power(n, 3) - ) - * S1 - ) - / (np.power(n, 2) * (1.0 + n) * (2.0 + n)) - ) - + ( - 0.2962962962962963 - * ( - -5184.0 - - 16992.0 * n - - 27808.0 * np.power(n, 2) - - 39024.0 * np.power(n, 3) - - 31384.0 * np.power(n, 4) - - 19422.0 * np.power(n, 5) - - 13965.0 * np.power(n, 6) - - 6819.0 * np.power(n, 7) - - 398.0 * np.power(n, 8) - + 1416.0 * np.power(n, 9) - + 547.0 * np.power(n, 10) - + 57.0 * np.power(n, 11) - ) - * S2 - ) - / ( - (-1.0 + n) - * np.power(n, 4) - * np.power(1.0 + n, 4) - * np.power(2.0 + n, 3) - ) - + S1 - * ( - ( - -0.06584362139917696 - * ( - -2670.0 - - 10217.0 * n - - 7454.0 * np.power(n, 2) - - 5165.0 * np.power(n, 3) - - 924.0 * np.power(n, 4) - + 230.0 * np.power(n, 5) - ) - ) - / (np.power(n, 2) * np.power(1.0 + n, 3) * (2.0 + n)) - + ( - 1.1851851851851851 - * ( - 24.0 - + 83.0 * n - + 49.0 * np.power(n, 2) - + 10.0 * np.power(n, 3) - ) - * S2 - ) - / (np.power(n, 2) * (1.0 + n) * (2.0 + n)) - ) - - (42.666666666666664 * (-2.0 - 3.0 * n + np.power(n, 2)) * S21) - / (np.power(n, 2) * (1.0 + n) * (2.0 + n)) - - ( - 0.19753086419753085 - * ( - 3888.0 - + 5376.0 * n - + 6832.0 * np.power(n, 2) - + 7472.0 * np.power(n, 3) - + 9129.0 * np.power(n, 4) - + 1736.0 * np.power(n, 5) - - 2382.0 * np.power(n, 6) - - 976.0 * np.power(n, 7) - + 29.0 * np.power(n, 8) - ) - * S3 - ) - / ( - (-1.0 + n) - * np.power(n, 3) - * np.power(1.0 + n, 3) - * np.power(2.0 + n, 2) - ) - + ( - (2.0 + n + np.power(n, 2)) - * ( - -8.772981689857207 * np.power(S1, 2) - - 1.1851851851851851 * np.power(S1, 4) - + 1.2020569031595942 - * ( - ( - -6.222222222222222 - * ( - -24.0 - - 28.0 * n - - 38.0 * np.power(n, 2) - - 17.0 * np.power(n, 3) - - 1.0 * np.power(n, 4) - + 9.0 * np.power(n, 5) - + 3.0 * np.power(n, 6) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * (2.0 + n) - ) - + 24.88888888888889 * S1 - ) - - 7.111111111111111 * np.power(S1, 2) * S2 - - 14.222222222222221 * np.power(S2, 2) - + 85.33333333333333 * S211 - + S1 * (-42.666666666666664 * S21 - 9.481481481481481 * S3) - - 42.666666666666664 * S31 - + 28.444444444444443 * S4 - ) - ) - / (n * (1.0 + n) * (2.0 + n)) - ) + -1706.6666666666665 + - 10875.259259259257 * n + - 33284.675378028754 * n**2 + - 64169.664061405594 * n**3 + - 84478.38609014948 * n**4 + - 79641.6883203241 * n**5 + - 34188.28213390343 * n**6 + + 50383.00160333119 * n**7 + + 137380.89089511195 * n**8 + + 163502.0013461959 * n**9 + + 100003.51351417531 * n**10 + + 3669.940256853264 * n**11 + - 48764.606785121505 * n**12 + - 45256.82055708685 * n**13 + - 22071.646154429887 * n**14 + - 6434.244292978784 * n**15 + - 1064.9350137879046 * n**16 + - 77.39386145946845 * n**17 ) - + 1.5 + - 1.646090534979424 + * n**4 + * (1.0 + n) ** 4 + * (2.0 + n) ** 3 + * (-3.84 - 6.98 * n + 9.83 * n**2 + 10.96 * n**3 + 3.31 * n**4 + n**5) + * S1**3 + + 0.49382716049382713 + * n**5 + * (1.0 + n) ** 5 + * (2.0 + n) ** 4 + * (2 + n + n**2) + * S1**4 + + (1 / (-1 + n)) + * 12.50566219331883 + * n**2 + * (1 + n) ** 2 + * (2 + n) ** 2 * ( - ( - -212.26414844076453 - * ( - -16.0 - - 14.0 * np.power(n, 2) - - 25.0 * np.power(n, 3) - - 5.0 * np.power(n, 4) - + 9.0 * np.power(n, 5) - + 3.0 * np.power(n, 6) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) - + 1.6449340668482262 - * ( - ( - 0.05555555555555555 - * ( - 3552.0 - + 17200.0 * n - + 46032.0 * np.power(n, 2) - + 76456.0 * np.power(n, 3) - + 88078.0 * np.power(n, 4) - + 65115.0 * np.power(n, 5) - + 27752.0 * np.power(n, 6) - + 2506.0 * np.power(n, 7) - - 1566.0 * np.power(n, 8) - - 261.0 * np.power(n, 9) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 3) - * np.power(1.0 + n, 3) - * np.power(2.0 + n, 3) - ) - - ( - 0.4444444444444444 - * ( - 288.0 - + 48.0 * n - - 3392.0 * np.power(n, 2) - - 5768.0 * np.power(n, 3) - - 3602.0 * np.power(n, 4) - + 1523.0 * np.power(n, 5) - + 5338.0 * np.power(n, 6) - + 4868.0 * np.power(n, 7) - + 2088.0 * np.power(n, 8) - + 337.0 * np.power(n, 9) - ) - * S1 - ) - / ( - (-1.0 + n) - * np.power(n, 3) - * np.power(1.0 + n, 3) - * np.power(2.0 + n, 3) - ) - + ( - 2.6666666666666665 - * ( - 36.0 - + 56.0 * n - + 29.0 * np.power(n, 2) - - 137.0 * np.power(n, 3) - - 120.0 * np.power(n, 4) - - 9.0 * np.power(n, 5) - + np.power(n, 6) - ) - * np.power(S1, 2) - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) - ) - + ( - (2.0 + n + np.power(n, 2)) - * ( - -212.26414844076453 * S1 - + 1.6449340668482262 - * ( - 32.0 * np.power(S1, 3) - - ( - 12.0 - * ( - -4.0 - - 4.0 * n - - 3.0 * np.power(n, 2) - + 2.0 * np.power(n, 3) - + np.power(n, 4) - ) - * S2 - ) - / ((-1.0 + n) * n * (1.0 + n) * (2.0 + n)) - - 8.0 * S3 - + ( - (-8.0 * (1.0 + 3.0 * n + 3.0 * np.power(n, 2))) - / (n * (1.0 + n)) - + 16.0 * S1 - ) - * Sm2 - + 16.0 * Sm21 - - 8.0 * Sm3 - ) - ) - ) - / (n * (1.0 + n) * (2.0 + n)) - ) - ) - + 4.5 - * ( - ( - 77.92727282720195 - * (-2.0 + n) - * (3.0 + n) - * ( - 4.0 - + 4.0 * n - + 7.0 * np.power(n, 2) - + 6.0 * np.power(n, 3) - + 3.0 * np.power(n, 4) - ) + -40.94145452557776 + - 144.43235346523267 * n + - 253.73592804740787 * n**2 + - 354.8177148989626 * n**3 + - 320.47393623567154 * n**4 + - 164.90366681355158 * n**5 + + 24.11092748813364 * n**6 + + 91.48066657983938 * n**7 + + 58.29138222882927 * n**8 + + 25.787008256870585 * n**9 + + 7.333676013446309 * n**10 + + n**11 ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) - + ( - 7.05120034829508 - * ( - -56.0 - - 20.0 * n - - 62.0 * np.power(n, 2) - - 75.0 * np.power(n, 3) - - 15.0 * np.power(n, 4) - + 27.0 * np.power(n, 5) - + 9.0 * np.power(n, 6) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) - + 1.6449340668482262 + * S2 + + 1.9259259259259258 + * n**5 + * (1 + n) ** 5 + * (2.0 + n) ** 4 + * (2 + n + n**2) + * S2**2 + + n**4 + * (1 + n) ** 3 + * (2 + n) ** 2 + * S1**2 * ( - ( - 0.2222222222222222 - * ( - -3456.0 - - 17184.0 * n - - 39184.0 * np.power(n, 2) - - 57200.0 * np.power(n, 3) - - 54000.0 * np.power(n, 4) - - 36634.0 * np.power(n, 5) - - 19177.0 * np.power(n, 6) - - 16952.0 * np.power(n, 7) - - 17658.0 * np.power(n, 8) - - 8937.0 * np.power(n, 9) - - 997.0 * np.power(n, 10) - + 1190.0 * np.power(n, 11) - + 552.0 * np.power(n, 12) - + 69.0 * np.power(n, 13) - ) - ) - / ( - np.power(-1.0 + n, 2) - * np.power(n, 4) - * np.power(1.0 + n, 4) - * np.power(2.0 + n, 4) - ) - + ( - 0.4444444444444444 - * ( - -864.0 - - 2160.0 * n - + 680.0 * np.power(n, 2) - + 2820.0 * np.power(n, 3) - + 3078.0 * np.power(n, 4) - - 601.0 * np.power(n, 5) - - 809.0 * np.power(n, 6) - + 1298.0 * np.power(n, 7) - + 1124.0 * np.power(n, 8) - + 515.0 * np.power(n, 9) - + 103.0 * np.power(n, 10) - ) - * S1 - ) - / ( - np.power(-1.0 + n, 2) - * np.power(n, 3) - * np.power(1.0 + n, 3) - * np.power(2.0 + n, 3) - ) - - ( - 1.3333333333333333 - * ( - -48.0 - - 116.0 * n - + 4.0 * np.power(n, 2) - - 85.0 * np.power(n, 3) - - 87.0 * np.power(n, 4) - + 33.0 * np.power(n, 5) - + 11.0 * np.power(n, 6) - ) - * np.power(S1, 2) - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) + -74.27160493827161 + - 300.6991145317517 * n + - 720.0024564166865 * n**2 + - 631.8555364768818 * n**3 + - 176.73340470935162 * n**4 + + 14.961120650448093 * n**5 + + 14.715435278544426 * n**6 + + 3.9681662390865937 * n**7 + + 12.296296296296296 + * n + * (1.0 + n) ** 2 + * (2.0 + n) ** 2 + * (2.0 + n + n**2) + * S2 ) - + ( - (2.0 + n + np.power(n, 2)) - * ( - 184.0593470475842 * S1 - + 1.6449340668482262 - * ( - -16.0 * np.power(S1, 3) - - ( - 1.3333333333333333 - * ( - -48.0 - - 70.0 * n - - 59.0 * np.power(n, 2) - + 22.0 * np.power(n, 3) - + 11.0 * np.power(n, 4) - ) - * S2 - ) - / ((-1.0 + n) * n * (1.0 + n) * (2.0 + n)) - - 32.0 * S1 * S2 - - 8.0 * S3 - + ( - ( - -2.6666666666666665 - * ( - -36.0 - - 58.0 * n - - 47.0 * np.power(n, 2) - + 22.0 * np.power(n, 3) - + 11.0 * np.power(n, 4) - ) - ) - / ((-1.0 + n) * n * (1.0 + n) * (2.0 + n)) - - 48.0 * S1 - ) - * Sm2 - + 16.0 * Sm21 - - 8.0 * Sm3 - ) - ) + - 8.88888888888889 + * n**4 + * (1.0 + n) ** 4 + * (2.0 + n) ** 3 + * (-6.4 - 15.2 * n + 2.6 * n**2 + 10 * n**3 + 3.8 * n**4 + n**5) + * S21 + - 6.222222222222222 + * n**5 + * (1.0 + n) ** 5 + * (2.0 + n) ** 4 + * (2.0 + n + n**2) + * S211 + - (1 / (-1.0 + n)) + * 21.16872427983539 + * n**3 + * (1.0 + n) ** 3 + * (2.0 + n) ** 3 + * ( + 12.093312597200622 + + 25.791601866251945 * n + + 37.262830482115085 * n**2 + + 35.36236391912908 * n**3 + + 43.72161741835148 * n**4 + + 31.71384136858476 * n**5 + + 14.762052877138414 * n**6 + + 3.878693623639191 * n**7 + + n**8 ) - / (n * (1.0 + n) * (2.0 + n)) - ) - + 0.8888888888888888 - * ( - (106.13207422038226 * (-1.0 + n) * (-2.0 + 3.0 * n + 3.0 * np.power(n, 2))) - / (np.power(n, 2) * np.power(1.0 + n, 2)) - + 1.6449340668482262 + * S3 + - 16.88888888888889 + * n**5 + * (1.0 + n) ** 5 + * (2.0 + n) ** 4 + * (2.0 + n + n**2) + * S31 + + 62.81481481481482 + * n**5 + * (1.0 + n) ** 5 + * (2.0 + n) ** 4 + * (2.0 + n + n**2) + * S4 + + 24.0 + * n**5 + * (1.0 + n) ** 3 + * (2.0 + n) ** 2 * ( - ( - 0.5 - * ( - 48.0 - + 184.0 * n - + 176.0 * np.power(n, 2) - - 222.0 * np.power(n, 3) - - 947.0 * np.power(n, 4) - - 1374.0 * np.power(n, 5) - - 1196.0 * np.power(n, 6) - - 612.0 * np.power(n, 7) - - 153.0 * np.power(n, 8) - ) - ) - / (np.power(n, 4) * np.power(1.0 + n, 4) * (2.0 + n)) - + ( - 8.0 - * ( - -10.0 - - 29.0 * n - - 21.0 * np.power(n, 2) - + 8.0 * np.power(n, 3) - + 39.0 * np.power(n, 4) - + 36.0 * np.power(n, 5) - + 13.0 * np.power(n, 6) - ) - * S1 - ) - / (np.power(n, 3) * np.power(1.0 + n, 3) * (2.0 + n)) - + ( - 4.0 - * ( - 20.0 - + 48.0 * n - + 43.0 * np.power(n, 2) - + 14.0 * np.power(n, 3) - + 3.0 * np.power(n, 4) - ) - * np.power(S1, 2) + 9.91735504245947 + - 8.888888888888888 * S1 + + 8.0 * S1**2 + + 13.333333333333334 * S2 + + n**6 + * ( + 1.1285582691963223 + - 1.111111111111111 * S1 + + 1.0 * S1**2 + + 1.6666666666666667 * S2 ) - / (np.power(n, 2) * np.power(1.0 + n, 2) * (2.0 + n)) - ) - + ( - 1.6449340668482262 - * (2.0 + n + np.power(n, 2)) + + n**5 * ( - -16.0 * np.power(S1, 3) - - (8.0 * (2.0 + 3.0 * n + 3.0 * np.power(n, 2)) * S2) - / (n * (1.0 + n)) - + 32.0 * S1 * S2 - + 16.0 * S3 - + (-16.0 / (n * (1.0 + n)) + 32.0 * S1) * Sm2 - - 32.0 * Sm21 - + 16.0 * Sm3 + 7.270278254744628 + - 6.444444444444444 * S1 + + 7.0 * S1**2 + + 11.666666666666666 * S2 ) - ) - / (n * (1.0 + n) * (2.0 + n)) - ) - + 0.75 - * ( - 1.6449340668482262 - * ( - ( - -0.4444444444444444 - * ( - 672.0 - + 3008.0 * n - + 5352.0 * np.power(n, 2) - + 6500.0 * np.power(n, 3) - + 5180.0 * np.power(n, 4) - + 3171.0 * np.power(n, 5) - + 2134.0 * np.power(n, 6) - + 1148.0 * np.power(n, 7) - + 414.0 * np.power(n, 8) - + 69.0 * np.power(n, 9) - ) + + n**4 + * ( + 27.0330569864561 + - 23.333333333333332 * S1 + + 21.0 * S1**2 + + 35.0 * S2 ) - / ( - (-1.0 + n) - * np.power(n, 3) - * np.power(1.0 + n, 3) - * np.power(2.0 + n, 3) + + n + * ( + 18.858890796756288 + - 49.77777777777777 * S1 + + 28.0 * S1**2 + + 46.666666666666664 * S2 ) - + ( - 17.77777777777778 - * ( - 4.0 - - 1.0 * n - + np.power(n, 2) - + 4.0 * np.power(n, 3) - + np.power(n, 4) - ) - * S1 + + n**3 + * ( + 51.79369299730096 + - 59.77777777777777 * S1 + + 37.0 * S1**2 + + 61.666666666666664 * S2 ) - / (n * np.power(1.0 + n, 2) * np.power(2.0 + n, 2)) - ) - + ( - 1.6449340668482262 - * (2.0 + n + np.power(n, 2)) + + n**2 * ( - 13.333333333333334 * np.power(S1, 2) - + 13.333333333333334 * S2 - + 26.666666666666668 * Sm2 + 45.17722508402332 + - 82.66666666666664 * S1 + + 42.0 * S1**2 + + 70.0 * S2 ) ) - / (n * (1.0 + n) * (2.0 + n)) - + nf + * Sm2 + + 26.666666666666664 + * n**5 + * (1.0 + n) ** 4 + * (2.0 + n) ** 3 + * (4.0 + 16.4 * n + 10.6 * n**2 + 2.8 * n**3 + n**4) + * Sm21 + + n**4 + * (1.0 + n) ** 2 + * (2.0 + n) + * S1 * ( - ( - -0.03292181069958848 - * ( - 3456.0 - + 18432.0 * n - + 33504.0 * np.power(n, 2) - - 22912.0 * np.power(n, 3) - - 281016.0 * np.power(n, 4) - - 465872.0 * np.power(n, 5) - - 806374.0 * np.power(n, 6) - - 1.459136e6 * np.power(n, 7) - - 1.48494e6 * np.power(n, 8) - - 377441.0 * np.power(n, 9) - + 849246.0 * np.power(n, 10) - + 1.139033e6 * np.power(n, 11) - + 692290.0 * np.power(n, 12) - + 237011.0 * np.power(n, 13) - + 44514.0 * np.power(n, 14) - + 3597.0 * np.power(n, 15) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 5) - * np.power(1.0 + n, 5) - * np.power(2.0 + n, 5) - ) - + ( - 0.09876543209876543 - * ( - 1256.0 - + 3172.0 * n - + 6816.0 * np.power(n, 2) - + 6430.0 * np.power(n, 3) - + 2355.0 * np.power(n, 4) - + 271.0 * np.power(n, 5) - + 22.0 * np.power(n, 6) - ) - * np.power(S1, 2) - ) - / (n * np.power(1.0 + n, 3) * np.power(2.0 + n, 3)) - - ( - 0.19753086419753085 - * ( - 134.0 - + 439.0 * n - + 344.0 * np.power(n, 2) - + 107.0 * np.power(n, 3) - + 20.0 * np.power(n, 4) - ) - * np.power(S1, 3) - ) - / (n * np.power(1.0 + n, 2) * np.power(2.0 + n, 2)) - + 1.6449340668482262 + (1 / (-1.0 + n)) * ( - ( - -0.4444444444444444 - * ( - 96.0 - + 224.0 * n - - 48.0 * np.power(n, 2) - - 244.0 * np.power(n, 3) - - 610.0 * np.power(n, 4) - - 501.0 * np.power(n, 5) - - 32.0 * np.power(n, 6) - + 146.0 * np.power(n, 7) - + 90.0 * np.power(n, 8) - + 15.0 * np.power(n, 9) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 3) - * np.power(1.0 + n, 3) - * np.power(2.0 + n, 3) - ) - - ( - 1.7777777777777777 - * ( - 20.0 - + 76.0 * n - + 59.0 * np.power(n, 2) - + 20.0 * np.power(n, 3) - + 5.0 * np.power(n, 4) - ) - * S1 - ) - / (n * np.power(1.0 + n, 2) * np.power(2.0 + n, 2)) - ) - + ( - 0.09876543209876543 - * ( - -1728.0 - - 4032.0 * n - - 3128.0 * np.power(n, 2) - - 6644.0 * np.power(n, 3) - + 7720.0 * np.power(n, 4) - + 15770.0 * np.power(n, 5) - + 6901.0 * np.power(n, 6) - + 806.0 * np.power(n, 7) - - 117.0 * np.power(n, 8) - + 4.0 * np.power(n, 9) - ) - * S2 - ) - / ( - (-1.0 + n) - * np.power(n, 3) - * np.power(1.0 + n, 3) - * np.power(2.0 + n, 3) - ) - + S1 + -519.7183890539501 + - 2800.054284509767 * n + - 3831.2973294216836 * n**2 + - 3450.917504245779 * n**3 + - 337.3605543706711 * n**4 + + 4392.313928071448 * n**5 + + 5284.589150336902 * n**6 + + 2749.8405498667044 * n**7 + + 725.8130102575197 * n**8 + + 90.15064415072688 * n**9 + + 0.6407789185504204 * n**10 + ) + - 13.82716049382716 + * (1.0 + n) ** 2 + * (2.0 + n) ** 2 * ( - ( - 0.06584362139917696 - * ( - 864.0 - - 2672.0 * n - - 11408.0 * np.power(n, 2) - - 73764.0 * np.power(n, 3) - - 73982.0 * np.power(n, 4) - + 29418.0 * np.power(n, 5) - + 87216.0 * np.power(n, 6) - + 61598.0 * np.power(n, 7) - + 23603.0 * np.power(n, 8) - + 5292.0 * np.power(n, 9) - + 491.0 * np.power(n, 10) - ) - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 4) - * np.power(2.0 + n, 4) - ) - - ( - 0.5925925925925926 - * ( - 214.0 - + 779.0 * n - + 544.0 * np.power(n, 2) - + 151.0 * np.power(n, 3) - + 40.0 * np.power(n, 4) - ) - * S2 - ) - / (n * np.power(1.0 + n, 2) * np.power(2.0 + n, 2)) - ) - - ( - 2.3703703703703702 - * ( - 20.0 - + 85.0 * n - + 50.0 * np.power(n, 2) - + 11.0 * np.power(n, 3) - + 5.0 * np.power(n, 4) - ) - * S21 - ) - / (n * np.power(1.0 + n, 2) * np.power(2.0 + n, 2)) - - ( - 0.3950617283950617 - * ( - 648.0 - + 496.0 * n - + 370.0 * np.power(n, 2) - + 725.0 * np.power(n, 3) - + 1155.0 * np.power(n, 4) - + 429.0 * np.power(n, 5) - + 65.0 * np.power(n, 6) - ) - * S3 - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) - + ( - 0.3950617283950617 - * ( - 448.0 - + 284.0 * n - + 1794.0 * np.power(n, 2) - + 2552.0 * np.power(n, 3) - + 1257.0 * np.power(n, 4) - + 278.0 * np.power(n, 5) - + 47.0 * np.power(n, 6) - ) - * Sm2 - ) - / (n * np.power(1.0 + n, 3) * np.power(2.0 + n, 3)) - + ( - 1.1851851851851851 - * ( - 216.0 - - 20.0 * n - - 548.0 * np.power(n, 2) - - 511.0 * np.power(n, 3) - - 339.0 * np.power(n, 4) - - 99.0 * np.power(n, 5) - + 5.0 * np.power(n, 6) - ) - * Sm3 - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) - - ( - 7.111111111111111 - * ( - 36.0 - - 20.0 * n - - 143.0 * np.power(n, 2) - - 61.0 * np.power(n, 3) - - 24.0 * np.power(n, 4) - - 9.0 * np.power(n, 5) - + 5.0 * np.power(n, 6) - ) - * (S1 * Sm2 - 1.0 * Sm21 + Sm3) - ) - / ( - (-1.0 + n) - * np.power(n, 2) - * np.power(1.0 + n, 2) - * np.power(2.0 + n, 2) - ) - + ( - (2.0 + n + np.power(n, 2)) - * ( - 1.2020569031595942 - * ( - (49.77777777777778 * (1.0 + n + np.power(n, 2))) - / ((-1.0 + n) * n * (1.0 + n) * (2.0 + n)) - - 24.88888888888889 * S1 - ) - + 1.1851851851851851 * np.power(S1, 4) - + 19.555555555555557 * np.power(S1, 2) * S2 - + 8.88888888888889 * np.power(S2, 2) - - 46.22222222222222 * S211 - + S1 * (24.88888888888889 * S21 + 69.92592592592592 * S3) - - 3.5555555555555554 * S31 - + 71.11111111111111 * S4 - + ( - (-64.0 * (-1.0 + 2.0 * n) * S1) / ((-1.0 + n) * n) - + 42.666666666666664 * S2 - ) - * Sm2 - + 1.6449340668482262 - * ( - 5.333333333333333 * np.power(S1, 2) - + 5.333333333333333 * S2 - + 10.666666666666666 * Sm2 - ) - + (64.0 * (-1.0 + 2.0 * n) * Sm21) / ((-1.0 + n) * n) - + 7.111111111111111 * Sm4 - - 21.333333333333332 * (S2 * Sm2 - 1.0 * Sm22 + Sm4) - - 10.666666666666666 * (S1 * Sm3 - 1.0 * Sm31 + Sm4) - + 64.0 - * ( - S2 * Sm2 - - 0.5 * (np.power(S1, 2) + S2) * Sm2 - + Sm211 - - 1.0 * Sm22 - + S1 * (S1 * Sm2 - 1.0 * Sm21 + Sm3) - - 1.0 * Sm31 - + Sm4 - ) - ) - ) - / (n * (1.0 + n) * (2.0 + n)) + -1.3714285714285714 + + 0.07857142857142857 * n + + 14.439285714285715 * n**2 + + 10.342857142857143 * n**3 + + 2.5964285714285715 * n**4 + + n**5 + ) + * S2 + + 4.444444444444445 + * n + * (1.0 + n) ** 3 + * (2.0 + n) ** 3 + * (2.0 + n + n**2) + * S21 + + 49.28395061728395 + * n + * (1.0 + n) ** 3 + * (2.0 + n) ** 3 + * (2.0 + n + n**2) + * S3 + - 48.0 * n * (1.0 + n) ** 3 * (2.0 + n) ** 3 * (2.0 + n + n**2) * Sm21 + ) + + 48.0 * n**5 * (1.0 + n) ** 5 * (2.0 + n) ** 4 * (2.0 + n + n**2) * Sm211 + - 32.0 * n**5 * (1.0 + n) ** 5 * (2.0 + n) ** 4 * (2.0 + n + n**2) * Sm22 + + 40.0 + * n**5 + * (1.0 + n) ** 4 + * (2.0 + n) ** 3 + * ( + -2.2222222222222223 + + 4.0 * S1 + + n**4 * (-0.5555555555555556 + S1) + + n**3 * (-1.5555555555555554 + 4.0 * S1) + + n**2 * (-5.888888888888888 + 7.0 * S1) + + n * (-9.11111111111111 + 8.0 * S1) ) + * Sm3 + - 40.0 * n**5 * (1.0 + n) ** 5 * (2.0 + n) ** 4 * (2.0 + n + n**2) * Sm31 + + 29.333333333333332 + * n**5 + * (1.0 + n) ** 5 + * (2.0 + n) ** 4 + * (2.0 + n + n**2) + * Sm4 ) ) + return aHg_nf0 + nf * aHg_nf1 diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py index a0a27759c..ccba54fdd 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py @@ -1,4 +1,5 @@ """The unpolarized, space-like |N3LO| heavy-quark |OME|.""" + # pylint: disable=too-many-lines import numba as nb import numpy as np @@ -14,7 +15,7 @@ def A_Hq(n, cache, nf, L): # pylint: disable=too-many-locals and :cite:`Blumlein:2017wxd` :eqref:`3.1`. When using the code, please cite the complete list of references - available in :mod:`ekore.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. The part proportional to :math:`n_f^0` includes non trivial weight-5 harmonics and has been parametrized in Mellin space. diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py index 5172f2e2e..d740f7810 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py @@ -1,27 +1,49 @@ """The unpolarized, space-like |N3LO| gluon-gluon |OME|.""" + # pylint: skip-file import numba as nb import numpy as np from .....harmonics import cache as c +from .....harmonics.log_functions import ( + lm11, + lm11m1, + lm11m2, + lm12, + lm12m1, + lm12m2, + lm13, + lm13m1, + lm13m2, + lm14m1, + lm14m2, +) @nb.njit(cache=True) def a_gg3(n, cache, nf): - r"""Compute the approximate part of :math:`a_{gg}^{S,(3)}(N)`. + r"""Compute :math:`a_{gg}^{(3)}(N)`. + + The expression is presented in :cite:`Ablinger:2022wbb`. + + The :math:`n_f^0` piece is parametrized from: - This is the part of :math:`A_{gg}^{S,(3)}(N)` proportional to :math:`\mathcal{O}(\epsilon^0)`, - the expression is presented in :cite:`Ablinger:2022wbb`. - It contains binomial factors which are approximated. + - the small-x limit :eqref:`4.10` + - the large-x limit :eqref:`4.11` + - the expansion of the local and singular parts in :eqref:`4.6, 4.7` + - the first 15 Mellin moments up to :math:`N=30` + + The analytical expression contains binomial factors + which are not practical to use. When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- n : complex Mellin moment - cache: numpy.ndarray + cache : numpy.ndarray Harmonic sum cache nf : int number of active flavor below the threshold @@ -29,37 +51,54 @@ def a_gg3(n, cache, nf): Returns ------- complex - :math:`a_{gg}^{S,(3)}(N)` + :math:`a_{gg}^{(3)}(N)` """ S1 = c.get(c.S1, cache, n) S2 = c.get(c.S2, cache, n) S3 = c.get(c.S3, cache, n) S4 = c.get(c.S4, cache, n) - S5 = c.get(c.S5, cache, n) + + Lm11 = lm11(n, S1) + Lm12 = lm12(n, S1, S2) + Lm13 = lm13(n, S1, S2, S3) + Lm11m1 = lm11m1(n, S1) + Lm12m1 = lm12m1(n, S1, S2) + Lm13m1 = lm13m1(n, S1, S2, S3) + Lm14m1 = lm14m1(n, S1, S2, S3, S4) + Lm11m2 = lm11m2(n, S1) + Lm12m2 = lm12m2(n, S1, S2) + Lm13m2 = lm13m2(n, S1, S2, S3) + Lm14m2 = lm14m2(n, S1, S2, S3, S4) # the nf^0 part is parametrized since it contains nasty binomial factors. agg3_nf0_param = ( - 119.55586399490849 - + 643.5919221725146 / (-1.0 + n) ** 2 - - 4243.672748386901 / (-1.0 + n) - - 1097.3959566791473 / n**6 - - 2166.223781401583 / n**5 - + 5864.212793800409 / n**4 - + 31055.955132702067 / n**3 - + 5195.523226994994 / n**2 - + 4052.670326185617 / n - + 723.5270116330819 * S1 - - (24416.76276706736 * S1) / n**4 - - (12798.647797499609 * S1) / n**3 - - (1191.9103600256221 * S1) / n**2 - - (411.7226853758584 * S1) / n - - 1.0287077597852439 * S1**2 - + 0.055958522352878494 * S1**3 - - 0.0011488227245772988 * S1**4 - + 68.79337566373333 * S2 - + 100.07538288542415 * S3 - + 110.06866836903241 * S4 - + 115.46020088075208 * S5 + 619.2420126046355 + + 701.1986854426286 / (-1.0 + n) ** 2 + - 4954.442786280953 / (-1.0 + n) + + 305.77777777777777 / n**6 + - 668.4444444444445 / n**5 + + 2426.352476661977 / n**4 + - 3148.735962235475 / n**3 + + 9155.33153602228 / n**2 + + 5069.820034891387 / n + - 6471.478696979203 / (1.0 + n) ** 2 + - 8987.70366338934 / (n + n**2) + - 21902.776840085757 / (2.0 + 3.0 * n + n**2) + - 78877.91436146703 / (3.0 + 4.0 * n + n**2) + - 207627.85210030797 / (6.0 + 5.0 * n + n**2) + + 860105.1673083167 / (6.0 + 11.0 * n + 6.0 * n**2 + n**3) + + 714.9711186248866 * S1 + + 576.0307099030653 * Lm11 + - 14825.806057017968 * Lm11m1 + + 368095.9894734118 * Lm11m2 + + 40.908173376688424 * Lm12 + - 6838.198890554838 * Lm12m1 + + 474165.7099083288 * Lm12m2 + + 5.333333333333333 * Lm13 + - 4424.7425689765805 * Lm13m1 + + 50838.65442166183 * Lm13m2 + - 508.9445773396529 * Lm14m1 + + 28154.716500168193 * Lm14m2 ) agg3_nf1 = 0.75 * ( -( @@ -253,7 +292,7 @@ def A_gg(n, cache, nf, L): The expression is presented in :cite:`Bierenbaum:2009mv`. When using the code, please cite the complete list of references - available in :mod:`ekore.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py index a75a90fe8..3296925c0 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py @@ -1,4 +1,5 @@ """The unpolarized, space-like |N3LO| gluon-quark |OME|.""" + import numba as nb import numpy as np @@ -12,7 +13,7 @@ def A_gq(n, cache, nf, L): # pylint: disable=too-many-locals The expression is presented in :cite:`Ablinger_2014` :eqref:`6.3`. When using the code, please cite the complete list of references - available in :mod:`ekore.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py index aa96a0dde..725c0ec84 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py @@ -1,4 +1,5 @@ """The unpolarized, space-like |N3LO| quark-gluon |OME|.""" + import numba as nb import numpy as np @@ -12,7 +13,7 @@ def A_qg(n, cache, nf, L): The expression is presented in :cite:`Bierenbaum:2009mv`. When using the code, please cite the complete list of references - available in :mod:`ekore.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py index f5a374f20..55e8b37fe 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py @@ -1,4 +1,5 @@ """The unpolarized, space-like |N3LO| quark-quark non-singlet |OME|.""" + import numba as nb import numpy as np @@ -14,9 +15,9 @@ def A_qqNS(n, cache, nf, L, eta): :cite:`Ablinger:2014vwa`. It contains some weight 5 harmonics sums. When using the code, please cite the complete list of references - available in :mod:`ekore.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. - Note the part proportional to nf^0 includes weight = 5 + Note the part proportional to :math:`n_f^0` includes weight = 5 harmonics and has been parametrized in Mellin space. For this piece the accuracy wrt the known moments is below the 0.01% (N<1000) and the absolute diff is within 5e-3. diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py index 743faaf34..50e6ccabd 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py @@ -1,4 +1,5 @@ """The unpolarized, space-like |N3LO| quark-quark pure-singlet |OME|.""" + import numba as nb import numpy as np @@ -12,7 +13,7 @@ def A_qqPS(n, cache, nf, L): The expression is presented in :cite:`Bierenbaum:2009mv`. When using the code, please cite the complete list of references - available in :mod:`ekore.matching_conditions.as3`. + available in :mod:`~ekore.operator_matrix_elements.unpolarized.space_like.as3`. Parameters ---------- diff --git a/tests/eko/evolution_operator/test_grid.py b/tests/eko/evolution_operator/test_grid.py index 804388db6..01754578a 100644 --- a/tests/eko/evolution_operator/test_grid.py +++ b/tests/eko/evolution_operator/test_grid.py @@ -72,7 +72,7 @@ def test_mod_expanded(theory_card, theory_ffns, operator_card, tmp_path: pathlib else: theory = theory_card theory.order = (1, 0) - theory.heavy.num_flavs_init = nf0 + operator_card.init = (operator_card.init[0], nf0) path.unlink(missing_ok=True) opgrid = legacy.Runner(theory, operator_card, path=path).op_grid opg = opgrid.compute() diff --git a/tests/eko/evolution_operator/test_init.py b/tests/eko/evolution_operator/test_init.py index 66112aff8..ed003f925 100644 --- a/tests/eko/evolution_operator/test_init.py +++ b/tests/eko/evolution_operator/test_init.py @@ -1,4 +1,5 @@ import os +from dataclasses import dataclass import numpy as np import pytest @@ -11,6 +12,7 @@ from eko.evolution_operator import Operator, quad_ker from eko.interpolation import InterpolatorDispatcher from eko.io.runcards import OperatorCard, ScaleVariationsMethod, TheoryCard +from eko.kernels import EvoMethods from eko.kernels import non_singlet as ns from eko.kernels import non_singlet_qed as qed_ns from eko.kernels import singlet as s @@ -25,9 +27,9 @@ def test_quad_ker_errors(): order=(1, 0), mode0=mode0, mode1=0, - method="", + method="iterate-exact", is_log=True, - logx=0.1, + logx=np.log(0.1), areas=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], as_list=[2.0, 1.0], mu2_from=1.0, @@ -60,15 +62,29 @@ def test_quad_ker(monkeypatch): monkeypatch.setattr(qed_ns, "dispatcher", lambda *args: 1.0) monkeypatch.setattr(s, "dispatcher", lambda *args: np.identity(2)) params = [ - ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.0, 0.0), - ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.123, 1.0), - ((3, 1), br.non_singlet_pids_map["ns+u"], 0, "", 0.0, 0.0), - ((1, 0), 100, 100, "", 0.123, 1.0), - ((1, 0), 100, 21, "", 0.0, 0.0), - ((1, 1), 100, 100, "iterate-exact", 0.123, 1.0), - ((1, 1), 100, 21, "iterate-exact", 0.123, 0.0), - ((1, 1), 10200, 10200, "iterate-exact", 0.123, 1.0), - ((1, 1), 10200, 10204, "iterate-exact", 0.123, 0.0), + ((1, 0), br.non_singlet_pids_map["ns+"], 0, EvoMethods.ITERATE_EXACT, 0.0, 0.0), + ( + (1, 0), + br.non_singlet_pids_map["ns+"], + 0, + EvoMethods.ITERATE_EXACT, + 0.123, + 1.0, + ), + ( + (3, 1), + br.non_singlet_pids_map["ns+u"], + 0, + EvoMethods.ITERATE_EXACT, + 0.0, + 0.0, + ), + ((1, 0), 100, 100, EvoMethods.ITERATE_EXACT, 0.123, 1.0), + ((1, 0), 100, 21, EvoMethods.ITERATE_EXACT, 0.0, 0.0), + ((1, 1), 100, 100, EvoMethods.ITERATE_EXACT, 0.123, 1.0), + ((1, 1), 100, 21, EvoMethods.ITERATE_EXACT, 0.123, 0.0), + ((1, 1), 10200, 10200, EvoMethods.ITERATE_EXACT, 0.123, 1.0), + ((1, 1), 10200, 10204, EvoMethods.ITERATE_EXACT, 0.123, 0.0), ] for order, mode0, mode1, method, logx, res in params: for is_log in [True, False]: @@ -107,7 +123,7 @@ def test_quad_ker(monkeypatch): order=(1, 0), mode0=label[0], mode1=label[1], - method="", + method=EvoMethods.ITERATE_EXACT, is_log=True, logx=0.123, areas=np.zeros(3), @@ -143,7 +159,7 @@ def test_quad_ker(monkeypatch): order=(1, 1), mode0=label[0], mode1=label[1], - method="iterate-exact", + method=EvoMethods.ITERATE_EXACT, is_log=True, logx=0.123, areas=np.zeros(3), @@ -171,7 +187,7 @@ def test_quad_ker(monkeypatch): order=(1, 0), mode0=br.non_singlet_pids_map["ns+"], mode1=0, - method="", + method=EvoMethods.ITERATE_EXACT, is_log=True, logx=0.0, areas=np.zeros(3), @@ -212,7 +228,12 @@ def compute(self, a_ref, nf, scale_from, scale_to): return a_ref -fake_managers = {"couplings": FakeCoupling()} +@dataclass(frozen=True) +class FakeManagers: + couplings: FakeCoupling + + +fake_managers = FakeManagers(couplings=FakeCoupling()) class TestOperator: @@ -436,7 +457,7 @@ def quad_ker_pegasus( order = (2, 0) mode0 = br.non_singlet_pids_map["ns+"] mode1 = 0 - method = "" + method = EvoMethods.ITERATE_EXACT logxs = np.log(int_disp.xgrid.raw) a1 = 1 a0 = 2 diff --git a/tests/eko/evolution_operator/test_init.py.patch b/tests/eko/evolution_operator/test_init.py.patch deleted file mode 100644 index 494f59a25..000000000 --- a/tests/eko/evolution_operator/test_init.py.patch +++ /dev/null @@ -1,601 +0,0 @@ -diff --git a/tests/eko/evolution_operator/test_init.py b/tests/eko/evolution_operator/test_init.py -index 47d5e700..2315a2cb 100644 ---- a/tests/eko/evolution_operator/test_init.py -+++ b/tests/eko/evolution_operator/test_init.py -@@ -5,7 +5,6 @@ import pytest - import scipy.integrate - - import eko.runner.legacy --import ekore.anomalous_dimensions.unpolarized.space_like as ad - from eko import basis_rotation as br - from eko import interpolation, mellin - from eko.evolution_operator import Operator, quad_ker -@@ -16,177 +15,176 @@ from eko.kernels import non_singlet_qed as qed_ns - from eko.kernels import singlet as s - from eko.matchings import Segment - -- --def test_quad_ker_errors(): -- for mode0 in [br.non_singlet_pids_map["ns+"], 21]: -- with pytest.raises(NotImplementedError): -- quad_ker( -- u=0.3, -- order=(1, 0), -- mode0=mode0, -- mode1=0, -- method="", -- is_log=True, -- logx=0.1, -- areas=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], -- as_list=[2.0, 1.0], -- mu2_from=1.0, -- mu2_to=2.0, -- a_half=np.array([[1.5, 0.01]]), -- alphaem_running=False, -- nf=3, -- L=0, -- ev_op_iterations=1, -- ev_op_max_order=(1, 0), -- sv_mode=1, -- is_threshold=False, -- is_polarized=True, -- is_time_like=True, -- n3lo_ad_variation=(0, 0, 0, 0), -- ) -+# def test_quad_ker_errors(): -+# for mode0 in [br.non_singlet_pids_map["ns+"], 21]: -+# with pytest.raises(NotImplementedError): -+# quad_ker( -+# u=0.3, -+# order=(1, 0), -+# mode0=mode0, -+# mode1=0, -+# method="", -+# is_log=True, -+# logx=0.1, -+# areas=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], -+# as_list=[2.0, 1.0], -+# mu2_from=1.0, -+# mu2_to=2.0, -+# a_half=np.array([[1.5, 0.01]]), -+# alphaem_running=False, -+# nf=3, -+# L=0, -+# ev_op_iterations=1, -+# ev_op_max_order=(1, 0), -+# sv_mode=1, -+# is_threshold=False, -+# is_polarized=True, -+# is_time_like=True, -+# n3lo_ad_variation=(0, 0, 0, 0), -+# ) - - --def test_quad_ker(monkeypatch): -- monkeypatch.setattr( -- mellin, "Talbot_path", lambda *args: 2 -- ) # N=2 is a safe evaluation point -- monkeypatch.setattr( -- mellin, "Talbot_jac", lambda *args: complex(0, np.pi) -- ) # negate mellin prefactor -- monkeypatch.setattr(interpolation, "log_evaluate_Nx", lambda *args: 1) -- monkeypatch.setattr(interpolation, "evaluate_Nx", lambda *args: 1) -- monkeypatch.setattr(ns, "dispatcher", lambda *args: 1.0) -- monkeypatch.setattr(qed_ns, "dispatcher", lambda *args: 1.0) -- monkeypatch.setattr(s, "dispatcher", lambda *args: np.identity(2)) -- params = [ -- ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.0, 0.0), -- ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.123, 1.0), -- ((3, 1), br.non_singlet_pids_map["ns+u"], 0, "", 0.0, 0.0), -- ((1, 0), 100, 100, "", 0.123, 1.0), -- ((1, 0), 100, 21, "", 0.0, 0.0), -- ((1, 1), 100, 100, "iterate-exact", 0.123, 1.0), -- ((1, 1), 100, 21, "iterate-exact", 0.123, 0.0), -- ((1, 1), 10200, 10200, "iterate-exact", 0.123, 1.0), -- ((1, 1), 10200, 10204, "iterate-exact", 0.123, 0.0), -- ] -- for order, mode0, mode1, method, logx, res in params: -- for is_log in [True, False]: -- for t, p in [(False, False), (False, True), (True, False)]: -- res_ns = quad_ker( -- u=0, -- order=order, -- mode0=mode0, -- mode1=mode1, -- method=method, -- is_log=is_log, -- logx=logx, -- areas=np.zeros(3), -- as_list=[2.0, 1.0], -- mu2_from=1, -- mu2_to=2, -- a_half=np.array([[1.5, 0.01]]), -- alphaem_running=False, -- nf=3, -- L=0, -- ev_op_iterations=0, -- ev_op_max_order=(0, 0), -- sv_mode=1, -- is_threshold=False, -- is_polarized=p, -- is_time_like=t, -- n3lo_ad_variation=(0, 0, 0, 0), -- ) -- np.testing.assert_allclose(res_ns, res) -- for label in [(br.non_singlet_pids_map["ns+"], 0), (100, 100)]: -- for sv in [2, 3]: -- for polarized in [True, False]: -- res_sv = quad_ker( -- u=0, -- order=(1, 0), -- mode0=label[0], -- mode1=label[1], -- method="", -- is_log=True, -- logx=0.123, -- areas=np.zeros(3), -- as_list=[2.0, 1.0], -- mu2_from=1, -- mu2_to=2, -- a_half=np.array([[1.5, 0.01]]), -- alphaem_running=False, -- nf=3, -- L=0, -- ev_op_iterations=0, -- ev_op_max_order=(1, 0), -- sv_mode=sv, -- is_threshold=False, -- is_polarized=polarized, -- is_time_like=False, -- n3lo_ad_variation=(0, 0, 0, 0), -- ) -- np.testing.assert_allclose(res_sv, 1.0) -- for label in [ -- (100, 100), -- (21, 21), -- (22, 22), -- (101, 101), -- (10200, 10200), -- (10204, 10204), -- (10202, 0), -- ]: -- for sv in [2, 3]: -- res_sv = quad_ker( -- u=0, -- order=(1, 1), -- mode0=label[0], -- mode1=label[1], -- method="iterate-exact", -- is_log=True, -- logx=0.123, -- areas=np.zeros(3), -- as_list=[2.0, 1.0], -- mu2_from=1, -- mu2_to=2, -- a_half=np.array([[1.5, 0.01]]), -- alphaem_running=False, -- nf=3, -- L=0, -- ev_op_iterations=0, -- ev_op_max_order=(1, 0), -- sv_mode=sv, -- is_threshold=False, -- n3lo_ad_variation=(0, 0, 0, 0), -- is_polarized=False, -- is_time_like=False, -- ) -- np.testing.assert_allclose(res_sv, 1.0) -+# def test_quad_ker(monkeypatch): -+# monkeypatch.setattr( -+# mellin, "Talbot_path", lambda *args: 2 -+# ) # N=2 is a safe evaluation point -+# monkeypatch.setattr( -+# mellin, "Talbot_jac", lambda *args: complex(0, np.pi) -+# ) # negate mellin prefactor -+# monkeypatch.setattr(interpolation, "log_evaluate_Nx", lambda *args: 1) -+# monkeypatch.setattr(interpolation, "evaluate_Nx", lambda *args: 1) -+# monkeypatch.setattr(ns, "dispatcher", lambda *args: 1.0) -+# monkeypatch.setattr(qed_ns, "dispatcher", lambda *args: 1.0) -+# monkeypatch.setattr(s, "dispatcher", lambda *args: np.identity(2)) -+# params = [ -+# ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.0, 0.0), -+# ((1, 0), br.non_singlet_pids_map["ns+"], 0, "", 0.123, 1.0), -+# ((3, 1), br.non_singlet_pids_map["ns+u"], 0, "", 0.0, 0.0), -+# ((1, 0), 100, 100, "", 0.123, 1.0), -+# ((1, 0), 100, 21, "", 0.0, 0.0), -+# ((1, 1), 100, 100, "iterate-exact", 0.123, 1.0), -+# ((1, 1), 100, 21, "iterate-exact", 0.123, 0.0), -+# ((1, 1), 10200, 10200, "iterate-exact", 0.123, 1.0), -+# ((1, 1), 10200, 10204, "iterate-exact", 0.123, 0.0), -+# ] -+# for order, mode0, mode1, method, logx, res in params: -+# for is_log in [True, False]: -+# for t, p in [(False, False), (False, True), (True, False)]: -+# res_ns = quad_ker( -+# u=0, -+# order=order, -+# mode0=mode0, -+# mode1=mode1, -+# method=method, -+# is_log=is_log, -+# logx=logx, -+# areas=np.zeros(3), -+# as_list=[2.0, 1.0], -+# mu2_from=1, -+# mu2_to=2, -+# a_half=np.array([[1.5, 0.01]]), -+# alphaem_running=False, -+# nf=3, -+# L=0, -+# ev_op_iterations=0, -+# ev_op_max_order=(0, 0), -+# sv_mode=1, -+# is_threshold=False, -+# is_polarized=p, -+# is_time_like=t, -+# n3lo_ad_variation=(0, 0, 0, 0), -+# ) -+# np.testing.assert_allclose(res_ns, res) -+# for label in [(br.non_singlet_pids_map["ns+"], 0), (100, 100)]: -+# for sv in [2, 3]: -+# for polarized in [True, False]: -+# res_sv = quad_ker( -+# u=0, -+# order=(1, 0), -+# mode0=label[0], -+# mode1=label[1], -+# method="", -+# is_log=True, -+# logx=0.123, -+# areas=np.zeros(3), -+# as_list=[2.0, 1.0], -+# mu2_from=1, -+# mu2_to=2, -+# a_half=np.array([[1.5, 0.01]]), -+# alphaem_running=False, -+# nf=3, -+# L=0, -+# ev_op_iterations=0, -+# ev_op_max_order=(1, 0), -+# sv_mode=sv, -+# is_threshold=False, -+# is_polarized=polarized, -+# is_time_like=False, -+# n3lo_ad_variation=(0, 0, 0, 0), -+# ) -+# np.testing.assert_allclose(res_sv, 1.0) -+# for label in [ -+# (100, 100), -+# (21, 21), -+# (22, 22), -+# (101, 101), -+# (10200, 10200), -+# (10204, 10204), -+# (10202, 0), -+# ]: -+# for sv in [2, 3]: -+# res_sv = quad_ker( -+# u=0, -+# order=(1, 1), -+# mode0=label[0], -+# mode1=label[1], -+# method="iterate-exact", -+# is_log=True, -+# logx=0.123, -+# areas=np.zeros(3), -+# as_list=[2.0, 1.0], -+# mu2_from=1, -+# mu2_to=2, -+# a_half=np.array([[1.5, 0.01]]), -+# alphaem_running=False, -+# nf=3, -+# L=0, -+# ev_op_iterations=0, -+# ev_op_max_order=(1, 0), -+# sv_mode=sv, -+# is_threshold=False, -+# n3lo_ad_variation=(0, 0, 0, 0), -+# is_polarized=False, -+# is_time_like=False, -+# ) -+# np.testing.assert_allclose(res_sv, 1.0) - -- monkeypatch.setattr(interpolation, "log_evaluate_Nx", lambda *args: 0) -- res_ns = quad_ker( -- u=0, -- order=(1, 0), -- mode0=br.non_singlet_pids_map["ns+"], -- mode1=0, -- method="", -- is_log=True, -- logx=0.0, -- areas=np.zeros(3), -- as_list=[2.0, 1.0], -- mu2_from=1, -- mu2_to=2, -- a_half=np.array([[1.5, 0.01]]), -- alphaem_running=False, -- nf=3, -- L=0, -- ev_op_iterations=0, -- ev_op_max_order=(0, 0), -- sv_mode=1, -- is_threshold=False, -- n3lo_ad_variation=(0, 0, 0, 0), -- is_polarized=False, -- is_time_like=False, -- ) -- np.testing.assert_allclose(res_ns, 0.0) -+# monkeypatch.setattr(interpolation, "log_evaluate_Nx", lambda *args: 0) -+# res_ns = quad_ker( -+# u=0, -+# order=(1, 0), -+# mode0=br.non_singlet_pids_map["ns+"], -+# mode1=0, -+# method="", -+# is_log=True, -+# logx=0.0, -+# areas=np.zeros(3), -+# as_list=[2.0, 1.0], -+# mu2_from=1, -+# mu2_to=2, -+# a_half=np.array([[1.5, 0.01]]), -+# alphaem_running=False, -+# nf=3, -+# L=0, -+# ev_op_iterations=0, -+# ev_op_max_order=(0, 0), -+# sv_mode=1, -+# is_threshold=False, -+# n3lo_ad_variation=(0, 0, 0, 0), -+# is_polarized=False, -+# is_time_like=False, -+# ) -+# np.testing.assert_allclose(res_ns, 0.0) - - - class FakeCoupling: -@@ -319,30 +317,30 @@ class TestOperator: - o.op_members[(br.non_singlet_pids_map["ns+"], 0)].value, - ) - -- def test_compute_no_skip_sv( -- self, monkeypatch, theory_ffns, operator_card, tmp_path -- ): -- tcard: TheoryCard = theory_ffns(3) -- tcard.xif = 2.0 -- ocard: OperatorCard = operator_card -- ocard.configs.scvar_method = ScaleVariationsMethod.EXPANDED -- r = eko.runner.legacy.Runner(tcard, ocard, path=tmp_path / "eko.tar") -- g = r.op_grid -- # setup objs -- o = Operator(g.config, g.managers, Segment(2.0, 2.0, 3)) -- # fake quad -- v = 0.1234 -- monkeypatch.setattr( -- scipy.integrate, "quad", lambda *args, v=v, **kwargs: (v, 0.56) -- ) -- o.compute() -- lx = len(ocard.xgrid.raw) -- res = np.full((lx, lx), v) -- res[-1, -1] = 1.0 -- # ns are all diagonal, so they start from an identity matrix -- for k in br.non_singlet_labels: -- assert k in o.op_members -- np.testing.assert_allclose(o.op_members[k].value, res, err_msg=k) -+ # def test_compute_no_skip_sv( -+ # self, monkeypatch, theory_ffns, operator_card, tmp_path -+ # ): -+ # tcard: TheoryCard = theory_ffns(3) -+ # tcard.xif = 2.0 -+ # ocard: OperatorCard = operator_card -+ # ocard.configs.scvar_method = ScaleVariationsMethod.EXPANDED -+ # r = eko.runner.legacy.Runner(tcard, ocard, path=tmp_path / "eko.tar") -+ # g = r.op_grid -+ # # setup objs -+ # o = Operator(g.config, g.managers, Segment(2.0, 2.0, 3)) -+ # # fake quad -+ # v = 0.1234 -+ # monkeypatch.setattr( -+ # scipy.integrate, "quad", lambda *args, v=v, **kwargs: (v, 0.56) -+ # ) -+ # o.compute() -+ # lx = len(ocard.xgrid.raw) -+ # res = np.full((lx, lx), v) -+ # res[-1, -1] = 1.0 -+ # # ns are all diagonal, so they start from an identity matrix -+ # for k in br.non_singlet_labels: -+ # assert k in o.op_members -+ # np.testing.assert_allclose(o.op_members[k].value, res, err_msg=k) - - def test_compute(self, monkeypatch, theory_ffns, operator_card, tmp_path): - tcard: TheoryCard = theory_ffns(3) -@@ -395,97 +393,97 @@ class TestOperator: - ) - - --def test_pegasus_path(): -- def quad_ker_pegasus( -- u, order, mode0, method, logx, areas, a1, a0, nf, ev_op_iterations -- ): -- # compute the mellin inversion as done in pegasus -- phi = 3 / 4 * np.pi -- c = 1.9 -- n = complex(c + u * np.exp(1j * phi)) -- gamma_ns = ad.gamma_ns(order, mode0, n, nf) -- ker = ns.dispatcher( -- order, -- method, -- gamma_ns, -- a1, -- a0, -- nf, -- ev_op_iterations, -- ) -- pj = interpolation.log_evaluate_Nx(n, logx, areas) -- return np.imag(np.exp(1j * phi) / np.pi * pj * ker) -+# def test_pegasus_path(): -+# def quad_ker_pegasus( -+# u, order, mode0, method, logx, areas, a1, a0, nf, ev_op_iterations -+# ): -+# # compute the mellin inversion as done in pegasus -+# phi = 3 / 4 * np.pi -+# c = 1.9 -+# n = complex(c + u * np.exp(1j * phi)) -+# gamma_ns = ad.gamma_ns(order, mode0, n, nf) -+# ker = ns.dispatcher( -+# order, -+# method, -+# gamma_ns, -+# a1, -+# a0, -+# nf, -+# ev_op_iterations, -+# ) -+# pj = interpolation.log_evaluate_Nx(n, logx, areas) -+# return np.imag(np.exp(1j * phi) / np.pi * pj * ker) - -- # It might be useful to test with a different function -- # monkeypatch.setattr(ns, "dispatcher", lambda x, *args: np.exp( - x ** 2 ) ) -- xgrid = np.geomspace(1e-7, 1, 10) -- int_disp = InterpolatorDispatcher(xgrid, 1, True) -- order = (2, 0) -- mode0 = br.non_singlet_pids_map["ns+"] -- mode1 = 0 -- method = "" -- logxs = np.log(int_disp.xgrid.raw) -- a1 = 1 -- a0 = 2 -- mu2_from = 1 -- mu2_to = 2**2 -- nf = 3 -- L = 0 -- ev_op_iterations = 10 -- for logx in logxs: -- for bf in int_disp: -- res_ns, _ = scipy.integrate.quad( -- quad_ker, -- 0.5, -- 1.0, -- args=( -- order, -- mode0, -- mode1, -- method, -- int_disp.log, -- logx, -- bf.areas_representation, -- [a0, a1], -- mu2_from, -- mu2_to, -- [[(a1 + a0) / 2, 0.00058]], -- False, -- nf, -- L, -- ev_op_iterations, -- 10, -- 0, -- False, -- (0, 0, 0, 0), -- False, -- False, -- ), -- epsabs=1e-12, -- epsrel=1e-5, -- limit=100, -- full_output=1, -- )[:2] -+# # It might be useful to test with a different function -+# # monkeypatch.setattr(ns, "dispatcher", lambda x, *args: np.exp( - x ** 2 ) ) -+# xgrid = np.geomspace(1e-7, 1, 10) -+# int_disp = InterpolatorDispatcher(xgrid, 1, True) -+# order = (2, 0) -+# mode0 = br.non_singlet_pids_map["ns+"] -+# mode1 = 0 -+# method = "" -+# logxs = np.log(int_disp.xgrid.raw) -+# a1 = 1 -+# a0 = 2 -+# mu2_from = 1 -+# mu2_to = 2**2 -+# nf = 3 -+# L = 0 -+# ev_op_iterations = 10 -+# for logx in logxs: -+# for bf in int_disp: -+# res_ns, _ = scipy.integrate.quad( -+# quad_ker, -+# 0.5, -+# 1.0, -+# args=( -+# order, -+# mode0, -+# mode1, -+# method, -+# int_disp.log, -+# logx, -+# bf.areas_representation, -+# [a0, a1], -+# mu2_from, -+# mu2_to, -+# [[(a1 + a0) / 2, 0.00058]], -+# False, -+# nf, -+# L, -+# ev_op_iterations, -+# 10, -+# 0, -+# False, -+# (0, 0, 0, 0), -+# False, -+# False, -+# ), -+# epsabs=1e-12, -+# epsrel=1e-5, -+# limit=100, -+# full_output=1, -+# )[:2] - -- res_test, _ = scipy.integrate.quad( -- quad_ker_pegasus, -- 0, -- np.inf, -- args=( -- order, -- mode0, -- method, -- logx, -- bf.areas_representation, -- a1, -- a0, -- nf, -- ev_op_iterations, -- ), -- epsabs=1e-12, -- epsrel=1e-5, -- limit=100, -- full_output=1, -- )[:2] -+# res_test, _ = scipy.integrate.quad( -+# quad_ker_pegasus, -+# 0, -+# np.inf, -+# args=( -+# order, -+# mode0, -+# method, -+# logx, -+# bf.areas_representation, -+# a1, -+# a0, -+# nf, -+# ev_op_iterations, -+# ), -+# epsabs=1e-12, -+# epsrel=1e-5, -+# limit=100, -+# full_output=1, -+# )[:2] - -- np.testing.assert_allclose(res_ns, res_test, rtol=2e-6) -+# np.testing.assert_allclose(res_ns, res_test, rtol=2e-6) diff --git a/tests/eko/evolution_operator/test_matching_condition.py b/tests/eko/evolution_operator/test_matching_condition.py index c854fb90c..bb6aeebbc 100644 --- a/tests/eko/evolution_operator/test_matching_condition.py +++ b/tests/eko/evolution_operator/test_matching_condition.py @@ -22,12 +22,6 @@ def mkOME(self): (br.matching_hplus_pid, 21), (200, 200), (br.matching_hminus_pid, 200), - ]: - ome.update({key: mkOM(self.shape)}) - return ome - - def update_intrinsic_OME(self, ome): - for key in [ (br.matching_hplus_pid, br.matching_hplus_pid), (br.matching_hminus_pid, br.matching_hminus_pid), (200, br.matching_hminus_pid), @@ -35,10 +29,11 @@ def update_intrinsic_OME(self, ome): (21, br.matching_hplus_pid), ]: ome.update({key: mkOM(self.shape)}) + return ome def test_split_ad_to_evol_map(self): ome = self.mkOME() - a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [], False) + a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1) triv_keys = [ "V.V", "T3.T3", @@ -55,6 +50,14 @@ def test_split_ad_to_evol_map(self): "c+.S", "c+.g", # "c-.V", + "S.c+", + "g.c+", + "c+.c+", + "c-.c-", + "b+.b+", + "b-.b-", + "t+.t+", + "t-.t-", ] assert sorted(str(k) for k in a.op_members.keys()) == sorted( [*triv_keys, *keys3] @@ -63,36 +66,8 @@ def test_split_ad_to_evol_map(self): a.op_members[member.MemberName("V.V")].value, ome[(200, 200)].value, ) - # # if alpha is zero, nothing non-trivial should happen - b = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [], False) - assert sorted(str(k) for k in b.op_members.keys()) == sorted( - [*triv_keys, *keys3] - ) - # assert_almost_equal( - # b.op_members[member.MemberName("V.V")].value, - # np.eye(self.shape[0]), - # ) - # nf=3 + IC - self.update_intrinsic_OME(ome) - c = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [4], False) - assert sorted(str(k) for k in c.op_members.keys()) == sorted( - [*triv_keys, *keys3, "S.c+", "g.c+", "c+.c+", "c-.c-"] - ) - assert_almost_equal( - c.op_members[member.MemberName("V.V")].value, - b.op_members[member.MemberName("V.V")].value, - ) - # nf=3 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [5], False) - assert sorted(str(k) for k in d.op_members.keys()) == sorted( - [*triv_keys, *keys3, "b+.b+", "b-.b-"] - ) - assert_almost_equal( - d.op_members[member.MemberName("b+.b+")].value, - np.eye(self.shape[0]), - ) # nf=4 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1, [5], False) + d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1) assert sorted(str(k) for k in d.op_members.keys()) == sorted( [ *triv_keys, @@ -106,6 +81,8 @@ def test_split_ad_to_evol_map(self): "b+.b+", # "b-.V", "b-.b-", + "t+.t+", + "t-.t-", ] ) assert_almost_equal( @@ -127,7 +104,7 @@ def test_split_ad_to_evol_map(self): def test_split_ad_to_evol_map_qed(self): ome = self.mkOME() - a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [], qed=True) + a = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, qed=True) triv_keys = [ "ph.ph", "S.S", @@ -144,7 +121,15 @@ def test_split_ad_to_evol_map_qed(self): keys3 = [ "c+.S", "c+.g", + "S.c+", + "g.c+", + "c+.c+", + "c-.c-", # "c-.V", + "b+.b+", + "b-.b-", + "t+.t+", + "t-.t-", ] assert sorted(str(k) for k in a.op_members.keys()) == sorted( [*triv_keys, *keys3] @@ -153,36 +138,8 @@ def test_split_ad_to_evol_map_qed(self): a.op_members[member.MemberName("V.V")].value, ome[(200, 200)].value, ) - # # if alpha is zero, nothing non-trivial should happen - b = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [], qed=True) - assert sorted(str(k) for k in b.op_members.keys()) == sorted( - [*triv_keys, *keys3] - ) - # assert_almost_equal( - # b.op_members[member.MemberName("V.V")].value, - # np.eye(self.shape[0]), - # ) - # nf=3 + IC - self.update_intrinsic_OME(ome) - c = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [4], qed=True) - assert sorted(str(k) for k in c.op_members.keys()) == sorted( - [*triv_keys, *keys3, "S.c+", "g.c+", "c+.c+", "c-.c-"] - ) - assert_almost_equal( - c.op_members[member.MemberName("V.V")].value, - b.op_members[member.MemberName("V.V")].value, - ) - # nf=3 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 3, 1, [5], qed=True) - assert sorted(str(k) for k in d.op_members.keys()) == sorted( - [*triv_keys, *keys3, "b+.b+", "b-.b-"] - ) - assert_almost_equal( - d.op_members[member.MemberName("b+.b+")].value, - np.eye(self.shape[0]), - ) # nf=4 + IB - d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1, [5], qed=True) + d = MatchingCondition.split_ad_to_evol_map(ome, 4, 1, qed=True) assert sorted(str(k) for k in d.op_members.keys()) == sorted( [ *triv_keys, @@ -196,6 +153,8 @@ def test_split_ad_to_evol_map_qed(self): "b+.b+", # "b-.V", "b-.b-", + "t+.t+", + "t-.t-", ] ) assert_almost_equal( diff --git a/tests/eko/evolution_operator/test_ome.py b/tests/eko/evolution_operator/test_ome.py index b844290c9..e807a587b 100644 --- a/tests/eko/evolution_operator/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -8,6 +8,7 @@ from eko import interpolation, mellin from eko import scale_variations as sv from eko.evolution_operator.operator_matrix_element import ( + MatchingMethods, OperatorMatrixElement, build_ome, quad_ker, @@ -33,7 +34,7 @@ def test_build_ome_as(): aS = A_singlet((o, 0), N, nf, L, is_msbar) for a in [aNS, aS]: - for method in [None, InversionMethod.EXPANDED, InversionMethod.EXACT]: + for method in MatchingMethods: dim = len(a[0]) if o != 1: assert len(a) == o @@ -53,7 +54,7 @@ def test_build_ome_nlo(): aNSi = A_non_singlet((1, 0), N, nf, L) aSi = A_singlet((1, 0), N, nf, L, is_msbar) for a in [aNSi, aSi]: - for method in [None, InversionMethod.EXPANDED, InversionMethod.EXACT]: + for method in MatchingMethods: dim = len(a[0]) # hh assert a[0, -1, -1] != 0.0 @@ -86,7 +87,7 @@ def test_quad_ker_errors(): is_log=True, logx=0.123, areas=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], - backward_method=None, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -119,7 +120,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.123, areas=np.zeros(3), - backward_method=None, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -138,7 +139,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.123, areas=np.zeros(3), - backward_method=None, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -157,7 +158,7 @@ def test_quad_ker(monkeypatch): is_log=is_log, logx=0.0, areas=np.zeros(3), - backward_method=None, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -191,7 +192,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.123, areas=np.zeros(3), - backward_method=InversionMethod.EXPANDED, + backward_method=MatchingMethods.BACKWARD_EXPANDED, a_s=0.0, nf=3, L=0.0, @@ -228,7 +229,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.123, areas=np.zeros(3), - backward_method=InversionMethod.EXACT, + backward_method=MatchingMethods.BACKWARD_EXACT, a_s=0.0, nf=3, L=0.0, @@ -252,7 +253,7 @@ def test_quad_ker(monkeypatch): is_log=True, logx=0.0, areas=np.array([0.01, 0.1, 1.0]), - backward_method=None, + backward_method=MatchingMethods.FORWARD, a_s=0.0, nf=3, L=0.0, @@ -338,6 +339,7 @@ def test_labels(self, theory_ffns, operator_card, tmp_path: pathlib.Path): path = tmp_path / "eko.tar" for skip_singlet in [True, False]: for skip_ns in [True, False]: + operator_card.configs.inversion_method = InversionMethod.EXACT operator_card.debug.skip_singlet = skip_singlet operator_card.debug.skip_non_singlet = skip_ns path.unlink(missing_ok=True) diff --git a/tests/eko/evolution_operator/test_physical.py b/tests/eko/evolution_operator/test_physical.py index e9882de5b..0ba41d91f 100644 --- a/tests/eko/evolution_operator/test_physical.py +++ b/tests/eko/evolution_operator/test_physical.py @@ -221,27 +221,21 @@ def mk_op_members(shape=(2, 2), qed=False): return om -def get_ad_to_evol_map(nf, intrinsic_range=None, qed=False): +def get_ad_to_evol_map(nf, qed=False): oms = mk_op_members(qed=qed) - m = PhysicalOperator.ad_to_evol_map(oms, nf, 1, intrinsic_range, qed) + m = PhysicalOperator.ad_to_evol_map(oms, nf, 1, qed) return sorted(map(str, m.op_members.keys())) def test_ad_to_evol_map(): triv_ops = ("S.S", "S.g", "g.S", "g.g", "V.V", "V3.V3", "T3.T3", "V8.V8", "T8.T8") # nf=3 - assert sorted(triv_ops) == get_ad_to_evol_map(3) - # nf=3 + IC - assert sorted([*triv_ops, "c+.c+", "c-.c-"]) == get_ad_to_evol_map(3, [4]) - # nf=3 + IC + IB assert sorted( - [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-"] - ) == get_ad_to_evol_map(3, [4, 5]) - # nf=4 + IC(non-existant) + IB - ks = sorted([*triv_ops, "V15.V15", "T15.T15", "b+.b+", "b-.b-"]) - assert ks == get_ad_to_evol_map(4, [4, 5]) - # nf=4 + IB - assert ks == get_ad_to_evol_map(4, [5]) + [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-", "t+.t+", "t-.t-"] + ) == get_ad_to_evol_map(3) + # nf=4 + ks = sorted([*triv_ops, "V15.V15", "T15.T15", "b+.b+", "b-.b-", "t+.t+", "t-.t-"]) + assert ks == get_ad_to_evol_map(4) # nf=6 assert sorted( [*triv_ops, "T15.T15", "V15.V15", "T24.T24", "V24.V24", "T35.T35", "V35.V35"] @@ -274,18 +268,12 @@ def test_ad_to_evol_map_qed(): "Td3.Td3", ) # nf=3 - assert sorted(triv_ops) == get_ad_to_evol_map(3, qed=True) - # nf=3 + IC - assert sorted([*triv_ops, "c+.c+", "c-.c-"]) == get_ad_to_evol_map(3, [4], qed=True) - # nf=3 + IC + IB assert sorted( - [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-"] - ) == get_ad_to_evol_map(3, [4, 5], qed=True) - # nf=4 + IC(non-existant) + IB - ks = sorted([*triv_ops, "Vu3.Vu3", "Tu3.Tu3", "b+.b+", "b-.b-"]) - assert ks == get_ad_to_evol_map(4, [4, 5], qed=True) - # nf=4 + IB - assert ks == get_ad_to_evol_map(4, [5], qed=True) + [*triv_ops, "c+.c+", "c-.c-", "b+.b+", "b-.b-", "t+.t+", "t-.t-"] + ) == get_ad_to_evol_map(3, True) + # nf=4 + ks = sorted([*triv_ops, "Vu3.Vu3", "Tu3.Tu3", "b+.b+", "b-.b-", "t+.t+", "t-.t-"]) + assert ks == get_ad_to_evol_map(4, True) # nf=6 assert sorted( [*triv_ops, "Tu3.Tu3", "Vu3.Vu3", "Td8.Td8", "Vd8.Vd8", "Tu8.Tu8", "Vu8.Vu8"] diff --git a/tests/eko/io/test_bases.py b/tests/eko/io/test_bases.py deleted file mode 100644 index a0165243f..000000000 --- a/tests/eko/io/test_bases.py +++ /dev/null @@ -1,83 +0,0 @@ -from dataclasses import fields - -import numpy as np - -from eko import basis_rotation as br -from eko import interpolation -from eko.io.bases import Bases - - -class TestBases: - XGRID_TEST = [1e-3, 1e-2, 1e-1, 1.0] - - def test_serialization(self): - rot = Bases(interpolation.XGrid(self.XGRID_TEST)) - - d = rot.raw - rot1 = rot.from_dict(d) - - for f in fields(Bases): - assert getattr(rot, f.name) == getattr(rot1, f.name) - - assert d["targetgrid"] is None - assert "_targetgrid" not in d - - def test_pids(self): - rot = Bases(interpolation.XGrid(self.XGRID_TEST)) - - # no check on correctness of value set - rot.inputpids = [0, 1] - # but the internal grid is unmodified - assert len(rot.pids) == 14 - # and fallback implemented for unset external bases - assert np.all(rot.targetpids == rot.pids) - - def test_grids(self): - rot = Bases(interpolation.XGrid(self.XGRID_TEST)) - - # no check on correctness of value set - rot.inputgrid = interpolation.XGrid([0.1, 1]) - # but the internal grid is unmodified - assert len(rot.xgrid) == len(self.XGRID_TEST) - # and fallback implemented for unset external grids - assert np.all(rot.targetgrid == rot.xgrid) - - def test_fallback(self): - xg = interpolation.XGrid([0.1, 1.0]) - r = Bases(xgrid=xg) - np.testing.assert_allclose(r.targetpids, r.pids) - np.testing.assert_allclose(r.inputpids, r.pids) - assert r.xgrid == xg - assert r.targetgrid == xg - assert r.inputgrid == xg - - def test_overwrite(self): - tpids = np.array([3, 4] + list(br.flavor_basis_pids[2:])) - ipids = np.array([5, 6] + list(br.flavor_basis_pids[2:])) - xg = interpolation.XGrid([0.1, 1.0]) - txg = interpolation.XGrid([0.2, 1.0]) - ixg = interpolation.XGrid([0.3, 1.0]) - r = Bases( - xgrid=xg, - _targetgrid=txg, - _inputgrid=ixg, - _targetpids=tpids, - _inputpids=ipids, - ) - np.testing.assert_allclose(r.targetpids, tpids) - np.testing.assert_allclose(r.inputpids, ipids) - assert r.xgrid == xg - assert r.targetgrid == txg - assert r.inputgrid == ixg - - def test_init(self): - xg = interpolation.XGrid([0.1, 1.0]) - txg = np.array([0.2, 1.0]) - ixg = {"grid": [0.3, 1.0], "log": True} - r = Bases(xgrid=xg, _targetgrid=txg, _inputgrid=ixg) - assert isinstance(r.xgrid, interpolation.XGrid) - assert isinstance(r.targetgrid, interpolation.XGrid) - assert isinstance(r.inputgrid, interpolation.XGrid) - assert r.xgrid == xg - assert r.targetgrid == interpolation.XGrid(txg) - assert r.inputgrid == interpolation.XGrid.load(ixg) diff --git a/tests/eko/io/test_manipulate.py b/tests/eko/io/test_manipulate.py index 3431d93ce..56ceafc0f 100644 --- a/tests/eko/io/test_manipulate.py +++ b/tests/eko/io/test_manipulate.py @@ -1,5 +1,3 @@ -import pathlib - import numpy as np import pytest @@ -21,235 +19,125 @@ def chk_keys(a, b): class TestManipulate: - def test_xgrid_reshape(self, eko_factory: EKOFactory, tmp_path: pathlib.Path): + def test_xgrid_reshape(self): # create object - muout = 10.0 - mu2out = muout**2 - epout = (mu2out, 5) + interpdeg = 1 xg = interpolation.XGrid(np.geomspace(1e-5, 1.0, 21)) - eko_factory.operator.mugrid = [(muout, 5)] - eko_factory.operator.xgrid = xg - o1 = eko_factory.get() + xgp = interpolation.XGrid(np.geomspace(1e-5, 1.0, 11)) lpids = 2 - o1[epout] = eko.io.Operator( + o1 = eko.io.Operator( operator=eko_identity([1, lpids, len(xg), lpids, len(xg)])[0] ) - xgp = interpolation.XGrid(np.geomspace(1e-5, 1.0, 11)) # only target - otpath = tmp_path / "ot.tar" - o1.deepcopy(otpath) - with EKO.edit(otpath) as ot: - manipulate.xgrid_reshape(ot, xgp) - chk_keys(o1.raw, ot.raw) - assert ot[epout].operator.shape == (lpids, len(xgp), lpids, len(xg)) - ottpath = tmp_path / "ott.tar" - o1.deepcopy(ottpath) - with EKO.edit(ottpath) as ott: - with pytest.warns(Warning): - manipulate.xgrid_reshape(ott, xg) - chk_keys(o1.raw, ott.raw) - np.testing.assert_allclose(ott[epout].operator, o1[epout].operator) + ot = manipulate.xgrid_reshape(o1, xg, interpdeg, xgp) + assert ot.operator.shape == (lpids, len(xgp), lpids, len(xg)) + ott = manipulate.xgrid_reshape(ot, xgp, interpdeg, xg) + # when blowing up again a line 0 ... 0 0 1 0 0 ... 0 becomes + # 0 ... 0 0.5 0 0.5 0 ... 0 instead + np.testing.assert_allclose( + np.sum(ott.operator, axis=3), np.sum(o1.operator, axis=3) + ) # only input - oipath = tmp_path / "oi.tar" - o1.deepcopy(oipath) - with EKO.edit(oipath) as oi: - manipulate.xgrid_reshape(oi, inputgrid=xgp) - assert oi[epout].operator.shape == (lpids, len(xg), lpids, len(xgp)) - chk_keys(o1.raw, oi.raw) - oiipath = tmp_path / "oii.tar" - o1.deepcopy(oiipath) - with EKO.edit(oiipath) as oii: - with pytest.warns(Warning): - manipulate.xgrid_reshape(oii, inputgrid=xg) - chk_keys(o1.raw, oii.raw) - np.testing.assert_allclose(oii[epout].operator, o1[epout].operator) + oi = manipulate.xgrid_reshape(o1, xg, interpdeg, inputgrid=xgp) + assert oi.operator.shape == (lpids, len(xg), lpids, len(xgp)) + oii = manipulate.xgrid_reshape(oi, xgp, interpdeg, inputgrid=xg) + np.testing.assert_allclose( + np.sum(oii.operator, axis=3), np.sum(o1.operator, axis=3) + ) + with pytest.warns(Warning): + oiii = manipulate.xgrid_reshape(oii, xg, interpdeg, inputgrid=xg) + np.testing.assert_allclose(oiii.operator, oii.operator) # both - oitpath = tmp_path / "oit.tar" - o1.deepcopy(oitpath) - with EKO.edit(oitpath) as oit: - manipulate.xgrid_reshape(oit, xgp, xgp) - chk_keys(o1.raw, oit.raw) - op = eko_identity([1, 2, len(xgp), 2, len(xgp)]) - np.testing.assert_allclose(oit[epout].operator, op[0], atol=1e-10) - + oit = manipulate.xgrid_reshape(o1, xg, interpdeg, xgp, xgp) + op = eko_identity([1, 2, len(xgp), 2, len(xgp)]) + np.testing.assert_allclose(oit.operator, op[0], atol=1e-10) # op error handling - ep2 = (25, 5) - o1[ep2] = eko.io.Operator( + o1e = eko.io.Operator( operator=eko_identity([1, lpids, len(xg), lpids, len(xg)])[0], error=0.1 * eko_identity([1, lpids, len(xg), lpids, len(xg)])[0], ) - ot2path = tmp_path / "ot2.tar" - o1.deepcopy(ot2path) - with EKO.edit(ot2path) as ot2: - manipulate.xgrid_reshape(ot2, xgp) - chk_keys(o1.raw, ot2.raw) - assert ot2[ep2].operator.shape == (lpids, len(xgp), lpids, len(xg)) - assert ot2[epout].error is None - assert ot2[ep2].error is not None + assert ot.error is None + assert oi.error is None + ot2 = manipulate.xgrid_reshape(o1e, xg, interpdeg, xgp) + assert ot2.error is not None # Python error - with pytest.raises(ValueError): - manipulate.xgrid_reshape(o1) + with pytest.raises(ValueError, match="Nor inputgrid nor targetgrid"): + manipulate.xgrid_reshape(o1, xg, interpdeg) - def test_reshape_io(self, eko_factory: EKOFactory, tmp_path): - eko_factory.path = tmp_path / "eko.tar" - eko_factory.operator.configs.interpolation_polynomial_degree = 1 - # create object - o1 = eko_factory.get() - lpids = len(o1.bases.pids) - path_copy = tmp_path / "eko_copy.tar" - o1.deepcopy(path_copy) - newxgrid = interpolation.XGrid([0.1, 1.0]) - inputpids = np.eye(lpids) - inputpids[:2, :2] = np.array([[1, -1], [1, 1]]) - with EKO.edit(path_copy) as o2: - manipulate.xgrid_reshape(o2, newxgrid, newxgrid) - manipulate.flavor_reshape(o2, inputpids=inputpids) - # reload - with EKO.read(path_copy) as o3: - chk_keys(o1.raw, o3.raw) - np.testing.assert_allclose(o3.bases.inputgrid.raw, newxgrid.raw) - np.testing.assert_allclose(o3.bases.targetgrid.raw, newxgrid.raw) - # since we use a general rotation, the inputpids are erased, - # leaving just as many zeros as PIDs, as placeholders for missing - # values - np.testing.assert_allclose(o3.bases.inputpids, [0] * len(o3.bases.pids)) - # these has to be unchanged - np.testing.assert_allclose(o3.bases.targetpids, o3.bases.pids) - - def test_flavor_reshape(self, eko_factory: EKOFactory, tmp_path: pathlib.Path): + def test_flavor_reshape(self): # create object xg = interpolation.XGrid(np.geomspace(1e-5, 1.0, 21)) - muout = 10.0 - mu2out = muout**2 - epout = (mu2out, 5) - eko_factory.operator.xgrid = xg - eko_factory.operator.mugrid = [(muout, 5)] - o1 = eko_factory.get() - lpids = len(o1.bases.pids) + lpids = len(br.flavor_basis_pids) lx = len(xg) - o1[epout] = eko.io.Operator( + o1 = eko.io.Operator( operator=eko_identity([1, lpids, lx, lpids, lx])[0], error=None, ) - # only target - target_r = np.eye(lpids) - target_r[:2, :2] = np.array([[1, -1], [1, 1]]) - tpath = tmp_path / "ot.tar" - ttpath = tmp_path / "ott.tar" - o1.deepcopy(tpath) - with EKO.edit(tpath) as ot: - manipulate.flavor_reshape(ot, target_r) - chk_keys(o1.raw, ot.raw) - assert ot[epout].operator.shape == (lpids, len(xg), lpids, len(xg)) - ot.deepcopy(ttpath) - with EKO.edit(ttpath) as ott: - manipulate.flavor_reshape(ott, np.linalg.inv(target_r)) - np.testing.assert_allclose(ott[epout].operator, o1[epout].operator) - with pytest.warns(Warning): - manipulate.flavor_reshape(ott, np.eye(lpids)) - chk_keys(o1.raw, ott.raw) - np.testing.assert_allclose(ott[epout].operator, o1[epout].operator) # only input input_r = np.eye(lpids) input_r[:2, :2] = np.array([[1, -1], [1, 1]]) - ipath = tmp_path / "oi.tar" - iipath = tmp_path / "oii.tar" - o1.deepcopy(ipath) - with EKO.edit(ipath) as oi: - manipulate.flavor_reshape(oi, inputpids=input_r) - chk_keys(o1.raw, oi.raw) - assert oi[epout].operator.shape == (lpids, len(xg), lpids, len(xg)) - oi.deepcopy(iipath) - with EKO.edit(iipath) as oii: - manipulate.flavor_reshape(oii, inputpids=np.linalg.inv(input_r)) - np.testing.assert_allclose(oii[epout].operator, o1[epout].operator) - with pytest.warns(Warning): - manipulate.flavor_reshape(oii, inputpids=np.eye(lpids)) - chk_keys(o1.raw, oii.raw) - np.testing.assert_allclose(oii[epout].operator, o1[epout].operator) + oi = manipulate.flavor_reshape(o1, inputpids=input_r) + assert oi.operator.shape == (lpids, len(xg), lpids, len(xg)) + oii = manipulate.flavor_reshape(oi, inputpids=np.linalg.inv(input_r)) + np.testing.assert_allclose(oii.operator, o1.operator) + with pytest.warns(Warning): + oiii = manipulate.flavor_reshape(oii, inputpids=np.eye(lpids)) + np.testing.assert_allclose(oiii.operator, oii.operator) + + # only target + target_r = np.eye(lpids) + target_r[:2, :2] = np.array([[1, -1], [1, 1]]) + ot = manipulate.flavor_reshape(o1, target_r) + assert ot.operator.shape == (lpids, len(xg), lpids, len(xg)) + ott = manipulate.flavor_reshape(ot, np.linalg.inv(target_r)) + np.testing.assert_allclose(ott.operator, o1.operator) + with pytest.warns(Warning): + ottt = manipulate.flavor_reshape(ott, np.eye(lpids)) + np.testing.assert_allclose(ottt.operator, ott.operator) # both - itpath = tmp_path / "oit.tar" - o1.deepcopy(itpath) - with EKO.edit(itpath) as oit: - manipulate.flavor_reshape(oit, target_r, input_r) - chk_keys(o1.raw, oit.raw) - op = eko_identity([1, lpids, len(xg), lpids, len(xg)]).copy() - np.testing.assert_allclose(oit[epout].operator, op[0], atol=1e-10) + oit = manipulate.flavor_reshape(o1, target_r, input_r) + op = eko_identity([1, lpids, len(xg), lpids, len(xg)]).copy() + np.testing.assert_allclose(oit.operator, op[0], atol=1e-10) # error - fpath = tmp_path / "fail.tar" - o1.deepcopy(fpath) - with pytest.raises(ValueError): - with EKO.edit(fpath) as of: - manipulate.flavor_reshape(of) + with pytest.raises(ValueError, match="Nor inputpids nor targetpids"): + manipulate.flavor_reshape(o1) - def test_to_evol(self, eko_factory: EKOFactory, tmp_path): + def test_to_evol(self): self._test_to_all_evol( - eko_factory, - tmp_path, manipulate.to_evol, br.rotate_flavor_to_evolution, - br.flavor_basis_pids, ) - def test_to_uni_evol(self, eko_factory: EKOFactory, tmp_path): + def test_to_uni_evol(self): self._test_to_all_evol( - eko_factory, - tmp_path, manipulate.to_uni_evol, br.rotate_flavor_to_unified_evolution, - br.flavor_basis_pids, ) - def _test_to_all_evol( - self, eko_factory: EKOFactory, tmp_path, to_evol_fnc, rot_matrix, pids - ): - xgrid = interpolation.XGrid([0.5, 1.0]) - mu_out = 2.0 - mu2_out = mu_out**2 - nfout = 4 - epout = (mu2_out, nfout) - eko_factory.operator.mu0 = float(np.sqrt(1.0)) - eko_factory.operator.mugrid = [(mu_out, nfout)] - eko_factory.operator.xgrid = xgrid - eko_factory.operator.configs.interpolation_polynomial_degree = 1 - eko_factory.operator.configs.interpolation_is_log = False - eko_factory.operator.configs.ev_op_max_order = (2, 0) - eko_factory.operator.configs.ev_op_iterations = 1 - eko_factory.operator.configs.inversion_method = runcards.InversionMethod.EXACT - o00 = eko_factory.get() - o01_path = tmp_path / "o01.tar" - o00.deepcopy(o01_path) - with EKO.edit(o01_path) as o01: - to_evol_fnc(o01) - o10_path = tmp_path / "o10.tar" - o00.deepcopy(o10_path) - with EKO.edit(o10_path) as o10: - to_evol_fnc(o10, False, True) - o11_path = tmp_path / "o11.tar" - o00.deepcopy(o11_path) - with EKO.edit(o11_path) as o11: - to_evol_fnc(o11, True, True) - chk_keys(o00.raw, o11.raw) - - with EKO.edit(o01_path) as o01: - with EKO.edit(o10_path) as o10: - with EKO.read(o11_path) as o11: - # check the input rotated one - np.testing.assert_allclose(o01.bases.inputpids, rot_matrix) - np.testing.assert_allclose(o01.bases.targetpids, pids) - # rotate also target - to_evol_fnc(o01, False, True) - np.testing.assert_allclose(o01[epout].operator, o11[epout].operator) - chk_keys(o00.raw, o01.raw) - # check the target rotated one - np.testing.assert_allclose(o10.bases.inputpids, pids) - np.testing.assert_allclose(o10.bases.targetpids, rot_matrix) - # rotate also input - to_evol_fnc(o10) - np.testing.assert_allclose(o10[epout].operator, o11[epout].operator) - chk_keys(o00.raw, o10.raw) + def _test_to_all_evol(self, to_evol_fnc, rot_matrix): + # create object + xg = interpolation.XGrid(np.geomspace(1e-5, 1.0, 21)) + lpids = len(br.flavor_basis_pids) + lx = len(xg) + o = eko.io.Operator( + operator=eko_identity([1, lpids, lx, lpids, lx])[0], + error=None, + ) + + # do it once + o01 = to_evol_fnc(o, True, False) + o10 = to_evol_fnc(o, False, True) + o11 = to_evol_fnc(o, True, True) + + # do also the other one + np.testing.assert_allclose( + to_evol_fnc(o01, False, True).operator, o11.operator, atol=1e-15 + ) + np.testing.assert_allclose( + to_evol_fnc(o10, True, False).operator, o11.operator, atol=1e-15 + ) diff --git a/tests/eko/io/test_metadata.py b/tests/eko/io/test_metadata.py index a5651e0c8..fcfa8dd09 100644 --- a/tests/eko/io/test_metadata.py +++ b/tests/eko/io/test_metadata.py @@ -3,11 +3,11 @@ import pytest import yaml -from eko.io import bases, metadata, paths +from eko.io import metadata, paths def test_metadata(tmp_path, caplog): - m = metadata.Metadata((1.0, 3), bases.Bases([0.1, 1.0])) + m = metadata.Metadata(origin=(1.0, 3), xgrid=[0.1, 1.0]) # errors with caplog.at_level(logging.INFO): m.update() @@ -26,7 +26,7 @@ def test_metadata(tmp_path, caplog): m.version = "0.0.0-a1~really1.0.0" m.update() # if I read back the thing should be what I set - mn = metadata.Metadata((1.0, 3), bases.Bases([0.1, 1.0])) + mn = metadata.Metadata(origin=(1.0, 3), xgrid=[0.1, 1.0]) mm = metadata.Metadata.load(tmp_path) assert m.path == tmp_path assert mm.version != mn.version diff --git a/tests/eko/io/test_runcards.py b/tests/eko/io/test_runcards.py index 6af37edcb..4fe9a8e4b 100644 --- a/tests/eko/io/test_runcards.py +++ b/tests/eko/io/test_runcards.py @@ -1,14 +1,10 @@ -import copy from io import StringIO import numpy as np import pytest import yaml -from banana.data.theories import default_card as theory_card from eko.io import runcards as rc -from eko.io.bases import Bases -from ekomark.data.operators import default_card as operator_card def test_flavored_mu2grid(): @@ -31,48 +27,6 @@ def test_flavored_mu2grid(): assert t == tuple(l) -def test_runcards_opcard(): - # check conversion - tc = copy.deepcopy(theory_card) - oc = copy.deepcopy(operator_card) - tc["Q0"] = 2.0 - # mugrid - oc["mugrid"] = [2.0, 10.0] - _nt, no = rc.update(tc, oc) - assert isinstance(no, rc.OperatorCard) - assert len(no.evolgrid) == len(oc["mugrid"]) - assert len(no.mu2grid) == len(no.evolgrid) - assert no.evolgrid[0][-1] == 4 - assert no.evolgrid[1][-1] == 5 - np.testing.assert_allclose(no.mu0, tc["Q0"]) - np.testing.assert_allclose(no.mu20, tc["Q0"] ** 2.0) - assert len(no.pids) == 14 - check_dumpable(no) - del oc["mugrid"] - # or mu2grid - oc["mu2grid"] = [9.0, 30.0, 32.0] - _nt, no = rc.update(tc, oc) - assert isinstance(no, rc.OperatorCard) - assert len(no.evolgrid) == len(oc["mu2grid"]) - assert len(no.mu2grid) == len(no.evolgrid) - assert no.evolgrid[0][-1] == 4 - assert no.evolgrid[1][-1] == 5 - assert no.evolgrid[2][-1] == 5 - check_dumpable(no) - del oc["mu2grid"] - # or Q2grid - oc["Q2grid"] = [15.0, 130.0, 140.0, 1e5] - _nt, no = rc.update(tc, oc) - assert isinstance(no, rc.OperatorCard) - assert len(no.evolgrid) == len(oc["Q2grid"]) - assert len(no.mu2grid) == len(no.evolgrid) - assert no.evolgrid[0][-1] == 4 - assert no.evolgrid[1][-1] == 5 - assert no.evolgrid[2][-1] == 5 - assert no.evolgrid[3][-1] == 6 - check_dumpable(no) - - def check_dumpable(no): """Check we can write and read to yaml.""" so = StringIO() @@ -81,50 +35,6 @@ def check_dumpable(no): noo = yaml.safe_load(so) -def test_runcards_ekomark(): - # check conversion - tc = copy.deepcopy(theory_card) - oc = copy.deepcopy(operator_card) - nt, no = rc.update(tc, oc) - assert isinstance(nt, rc.TheoryCard) - assert isinstance(no, rc.OperatorCard) - # check is idempotent - nnt, nno = rc.update(nt, no) - assert nnt == nt - assert nno == no - - -def test_runcards_quarkmass(): - tc = copy.deepcopy(theory_card) - tc["nfref"] = 5 - tc["IC"] = 1 - oc = copy.deepcopy(operator_card) - nt, no = rc.update(tc, oc) - assert nt.heavy.intrinsic_flavors == [4] - for _, scale in nt.heavy.masses: - assert np.isnan(scale) - m2s = rc.masses(nt, no.configs.evolution_method) - raw = rc.Legacy.heavies("m%s", tc) - raw2 = np.power(raw, 2.0) - np.testing.assert_allclose(m2s, raw2) - tc["HQ"] = "MSBAR" - tc["Qmc"] = raw[0] * 1.1 - tc["Qmb"] = raw[1] * 1.1 - tc["Qmt"] = raw[2] * 0.9 - nt, no = rc.update(tc, oc) - for _, scale in nt.heavy.masses: - assert not np.isnan(scale) - m2s = rc.masses(nt, no.configs.evolution_method) - for m1, m2 in zip(m2s, raw2): - assert not np.isclose(m1, m2) - tc["HQ"] = "Blub" - with pytest.raises(ValueError, match="mass scheme"): - _nt, _no = rc.update(tc, oc) - nt.heavy.masses_scheme = "Bla" - with pytest.raises(ValueError, match="mass scheme"): - _ms = rc.masses(nt, no.configs.evolution_method) - - def test_legacy_fallback(): assert rc.Legacy.fallback(1, 2, 3) == 1 assert rc.Legacy.fallback(None, 2, 3) == 2 diff --git a/tests/eko/kernels/test_init.py b/tests/eko/kernels/test_init.py new file mode 100644 index 000000000..3717de275 --- /dev/null +++ b/tests/eko/kernels/test_init.py @@ -0,0 +1,21 @@ +from eko.io.types import EvolutionMethod +from eko.kernels import EvoMethods, ev_method + + +def test_ev_method(): + methods = { + "iterate-expanded": EvoMethods.ITERATE_EXPANDED, + "decompose-expanded": EvoMethods.DECOMPOSE_EXPANDED, + "perturbative-expanded": EvoMethods.PERTURBATIVE_EXPANDED, + "truncated": EvoMethods.TRUNCATED, + "ordered-truncated": EvoMethods.ORDERED_TRUNCATED, + "iterate-exact": EvoMethods.ITERATE_EXACT, + "decompose-exact": EvoMethods.DECOMPOSE_EXACT, + "perturbative-exact": EvoMethods.PERTURBATIVE_EXACT, + } + assert len(methods.keys()) == len(EvolutionMethod) + assert len(methods.keys()) == len(EvoMethods) + for s, i in methods.items(): + j = ev_method(EvolutionMethod(s)) + assert j == i + assert isinstance(j, int) diff --git a/tests/eko/kernels/test_kernels_QEDns.py b/tests/eko/kernels/test_kernels_QEDns.py index bb18c3e17..bfa655a81 100644 --- a/tests/eko/kernels/test_kernels_QEDns.py +++ b/tests/eko/kernels/test_kernels_QEDns.py @@ -3,6 +3,7 @@ from eko import basis_rotation as br from eko.couplings import Couplings +from eko.kernels import EvoMethods from eko.kernels import non_singlet_qed as ns from eko.quantities.couplings import CouplingEvolutionMethod, CouplingsInfo from eko.quantities.heavy_quarks import QuarkMassScheme @@ -14,7 +15,7 @@ # "perturbative-expanded", # "truncated", # "ordered-truncated", - "iterate-exact", + EvoMethods.ITERATE_EXACT, # "decompose-exact", # "perturbative-exact", ] @@ -119,9 +120,7 @@ def test_zero_true_gamma(): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=5, - max_num_flavs=6, + ref=(muref, 5), ) ) evmod = CouplingEvolutionMethod.EXACT diff --git a/tests/eko/kernels/test_kernels_QEDsinglet.py b/tests/eko/kernels/test_kernels_QEDsinglet.py index b953c053c..2fee4e17f 100644 --- a/tests/eko/kernels/test_kernels_QEDsinglet.py +++ b/tests/eko/kernels/test_kernels_QEDsinglet.py @@ -1,6 +1,7 @@ import numpy as np import pytest +from eko.kernels import EvoMethods from eko.kernels import singlet_qed as s from ekore.anomalous_dimensions.unpolarized import space_like as ad @@ -10,7 +11,7 @@ # "perturbative-expanded", # "truncated", # "ordered-truncated", - "iterate-exact", + EvoMethods.ITERATE_EXACT, # "decompose-exact", # "perturbative-exact", ] @@ -125,5 +126,12 @@ def test_zero_true_gamma(monkeypatch): def test_error(): with pytest.raises(NotImplementedError): s.dispatcher( - (3, 2), "AAA", np.random.rand(4, 3, 2, 2), [0.2, 0.1], [0.01], 3, 10, 10 + (3, 2), + "iterate-exact", + np.random.rand(4, 3, 2, 2), + [0.2, 0.1], + [0.01], + 3, + 10, + 10, ) diff --git a/tests/eko/kernels/test_kernels_QEDvalence.py b/tests/eko/kernels/test_kernels_QEDvalence.py index 29f0f3d7a..4b12a492b 100644 --- a/tests/eko/kernels/test_kernels_QEDvalence.py +++ b/tests/eko/kernels/test_kernels_QEDvalence.py @@ -1,6 +1,7 @@ import numpy as np import pytest +from eko.kernels import EvoMethods from eko.kernels import valence_qed as val from ekore import anomalous_dimensions @@ -10,13 +11,13 @@ # "perturbative-expanded", # "truncated", # "ordered-truncated", - "iterate-exact", + EvoMethods.ITERATE_EXACT, # "decompose-exact", # "perturbative-exact", ] -def test_zero(monkeypatch): +def test_zero(): """No evolution results in exp(0)""" nf = 3 ev_op_iterations = 2 @@ -57,7 +58,7 @@ def test_zero(monkeypatch): ) -def test_zero_true_gamma(monkeypatch): +def test_zero_true_gamma(): """No evolution results in exp(0)""" nf = 3 ev_op_iterations = 2 @@ -101,5 +102,12 @@ def test_zero_true_gamma(monkeypatch): def test_error(): with pytest.raises(NotImplementedError): val.dispatcher( - (3, 2), "AAA", np.random.rand(4, 3, 2, 2), [0.2, 0.1], [0.01], 3, 10, 10 + (3, 2), + "iterate-exact", + np.random.rand(4, 3, 2, 2), + [0.2, 0.1], + [0.01], + 3, + 10, + 10, ) diff --git a/tests/eko/kernels/test_ns.py b/tests/eko/kernels/test_ns.py index 86abef4bf..70e7faf8d 100644 --- a/tests/eko/kernels/test_ns.py +++ b/tests/eko/kernels/test_ns.py @@ -5,19 +5,9 @@ import ekore.anomalous_dimensions.unpolarized.space_like as ad from eko import beta +from eko.kernels import EvoMethods from eko.kernels import non_singlet as ns -methods = [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", - "truncated", - "ordered-truncated", - "iterate-exact", - "decompose-exact", - "perturbative-exact", -] - def test_zero(): """No evolution results in exp(0)""" @@ -25,7 +15,7 @@ def test_zero(): ev_op_iterations = 2 gamma_ns = np.array([1 + 0.0j, 1 + 0j, 1 + 0j, 1 + 0j]) for order in [1, 2, 3, 4]: - for method in methods: + for method in EvoMethods: np.testing.assert_allclose( ns.dispatcher( (order, 0), method, gamma_ns, 1.0, 1.0, nf, ev_op_iterations @@ -54,7 +44,7 @@ def test_ode_lo(): a0 = 0.3 for a1 in [0.1, 0.2]: r = a1 * gamma_ns / (beta.beta_qcd((2, 0), nf) * a1**2) - for method in methods: + for method in EvoMethods: rhs = r * ns.dispatcher( (1, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -91,7 +81,7 @@ def test_ode_nlo(): r = (a1 * gamma_ns[0] + a1**2 * gamma_ns[1]) / ( beta.beta_qcd((2, 0), nf) * a1**2 + beta.beta_qcd((3, 0), nf) * a1**3 ) - for method in ["iterate-exact"]: + for method in [EvoMethods.ITERATE_EXACT]: rhs = r * ns.dispatcher( (2, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -130,7 +120,7 @@ def test_ode_nnlo(): + beta.beta_qcd((3, 0), nf) * a1**2 + beta.beta_qcd((4, 0), nf) * a1**3 ) - for method in ["iterate-exact"]: + for method in [EvoMethods.ITERATE_EXACT]: rhs = r * ns.dispatcher( (3, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -165,17 +155,14 @@ def test_ode_n3lo(): a0 = 0.3 for a1 in [0.1, 0.2]: r = ( - gamma_ns[0] - + a1 * gamma_ns[1] - + a1**2 * gamma_ns[2] - + a1**3 * gamma_ns[3] + gamma_ns[0] + a1 * gamma_ns[1] + a1**2 * gamma_ns[2] + a1**3 * gamma_ns[3] ) / ( beta.beta_qcd((2, 0), nf) * a1 + beta.beta_qcd((3, 0), nf) * a1**2 + beta.beta_qcd((4, 0), nf) * a1**3 + beta.beta_qcd((5, 0), nf) * a1**4 ) - for method in ["iterate-exact"]: + for method in [EvoMethods.ITERATE_EXACT]: rhs = r * ns.dispatcher( (4, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -205,7 +192,9 @@ def test_ode_n3lo(): def test_error(monkeypatch): monkeypatch.setattr("eko.beta.beta_qcd", lambda *_args: 1.0) with pytest.raises(NotImplementedError, match="order is not implemented"): - ns.dispatcher((5, 0), "iterate-exact", np.random.rand(3) + 0j, 0.2, 0.1, 3, 10) + ns.dispatcher( + (5, 0), EvoMethods.ITERATE_EXACT, np.random.rand(3) + 0j, 0.2, 0.1, 3, 10 + ) with pytest.raises(NotImplementedError): ad.gamma_ns((2, 0), 10202, 1, (0, 0, 0, 0, 0, 0, 0), 3) @@ -219,7 +208,7 @@ def test_gamma_usage(): gamma_ns = np.full(4, np.nan) for order in range(1, 5): gamma_ns[order - 1] = np.random.rand() - for method in methods: + for method in EvoMethods: r = ns.dispatcher( (order, 0), method, gamma_ns, a1, a0, nf, ev_op_iterations ) @@ -228,8 +217,8 @@ def test_gamma_usage(): for order in range(1, 5): gamma_ns = np.random.rand(order) gamma_ns[order - 1] = np.nan - for method in methods: - if method == "ordered-truncated": + for method in EvoMethods: + if method is EvoMethods.ORDERED_TRUNCATED: # we are actually dividing by a np.nan, # since the sum of U vec is nan warnings.simplefilter("ignore", RuntimeWarning) diff --git a/tests/eko/kernels/test_s.py b/tests/eko/kernels/test_s.py index 5380ba319..ff4fdfc0d 100644 --- a/tests/eko/kernels/test_s.py +++ b/tests/eko/kernels/test_s.py @@ -3,20 +3,10 @@ import numpy as np import pytest +from eko.kernels import EvoMethods from eko.kernels import singlet as s from ekore import anomalous_dimensions as ad -methods = [ - "iterate-expanded", - "decompose-expanded", - "perturbative-expanded", - "truncated", - "ordered-truncated", - "iterate-exact", - "decompose-exact", - "perturbative-exact", -] - def test_zero_lo(monkeypatch): """No evolution results in exp(0)""" @@ -35,7 +25,7 @@ def test_zero_lo(monkeypatch): np.array([[0, 0], [0, 1]]), ), ) - for method in methods: + for method in EvoMethods: np.testing.assert_allclose( s.dispatcher( (1, 0), method, gamma_s, 1, 1, nf, ev_op_iterations, ev_op_max_order @@ -75,8 +65,8 @@ def test_zero_nlo_decompose(monkeypatch): ), ) for method in [ - "decompose-expanded", - "decompose-exact", + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.DECOMPOSE_EXACT, ]: np.testing.assert_allclose( s.dispatcher( @@ -117,8 +107,8 @@ def test_zero_nnlo_decompose(monkeypatch): ), ) for method in [ - "decompose-expanded", - "decompose-exact", + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.DECOMPOSE_EXACT, ]: np.testing.assert_allclose( s.dispatcher( @@ -159,8 +149,8 @@ def test_zero_n3lo_decompose(monkeypatch): ), ) for method in [ - "decompose-expanded", - "decompose-exact", + EvoMethods.DECOMPOSE_EXPANDED, + EvoMethods.DECOMPOSE_EXACT, ]: np.testing.assert_allclose( s.dispatcher( @@ -200,7 +190,7 @@ def test_similarity(): ]: ref = s.dispatcher( order, - "decompose-exact", + EvoMethods.DECOMPOSE_EXACT, gamma_s, a1, a0, @@ -208,7 +198,7 @@ def test_similarity(): ev_op_iterations, ev_op_max_order, ) - for method in methods: + for method in EvoMethods: np.testing.assert_allclose( s.dispatcher( order, @@ -227,7 +217,9 @@ def test_similarity(): def test_error(): with pytest.raises(NotImplementedError): - s.dispatcher((4, 0), "AAA", np.random.rand(3, 2, 2), 0.2, 0.1, 3, 10, 10) + s.dispatcher( + (4, 0), "iterate-exact", np.random.rand(3, 2, 2), 0.2, 0.1, 3, 10, 10 + ) def mk_almost_diag_matrix(n, max_ang=np.pi / 8.0): @@ -247,7 +239,7 @@ def test_gamma_usage(): gamma_s = np.full((4, 2, 2), np.nan) for order in range(1, 5): gamma_s[order - 1] = mk_almost_diag_matrix(1) - for method in methods: + for method in EvoMethods: r = s.dispatcher( (order, 0), method, @@ -263,8 +255,8 @@ def test_gamma_usage(): for order in range(1, 5): gamma_s = mk_almost_diag_matrix(4) gamma_s[order - 1] = np.full((2, 2), np.nan) - for method in methods: - if "iterate" in method: + for method in EvoMethods: + if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: # we are actually dividing by the determinant of # matrix full of np.nan warnings.simplefilter("ignore", RuntimeWarning) @@ -287,8 +279,8 @@ def test_singlet_back(): nf = 4 a1 = 3.0 a0 = 4.0 - s10 = s.dispatcher(order, "iterate-exact", gamma_s, a1, a0, nf, 15, 1) + s10 = s.dispatcher(order, EvoMethods.ITERATE_EXACT, gamma_s, a1, a0, nf, 15, 1) np.testing.assert_allclose( np.linalg.inv(s10), - s.dispatcher(order, "iterate-exact", gamma_s, a0, a1, nf, 15, 1), + s.dispatcher(order, EvoMethods.ITERATE_EXACT, gamma_s, a0, a1, nf, 15, 1), ) diff --git a/tests/eko/kernels/test_utils.py b/tests/eko/kernels/test_utils.py deleted file mode 100644 index 5cb33e23d..000000000 --- a/tests/eko/kernels/test_utils.py +++ /dev/null @@ -1,12 +0,0 @@ -import numpy as np - -from eko.kernels import utils - - -def test_geomspace(): - for start in [1, 2]: - for end in [3, 4]: - for n in [5, 10]: - np.testing.assert_allclose( - utils.geomspace(start, end, n), np.geomspace(start, end, n) - ) diff --git a/tests/eko/quantities/test_couplings.py b/tests/eko/quantities/test_couplings.py index 0a3b97415..e4d194d5b 100644 --- a/tests/eko/quantities/test_couplings.py +++ b/tests/eko/quantities/test_couplings.py @@ -3,7 +3,7 @@ def test_couplings_ref(): scale = 90.0 - d = dict(alphas=0.1, alphaem=0.01, scale=scale, max_num_flavs=6, num_flavs_ref=None) + d = dict(alphas=0.1, alphaem=0.01, ref=(scale, 5)) couplings = CouplingsInfo.from_dict(d) - assert couplings.scale == scale + assert couplings.ref[0] == scale assert not couplings.em_running diff --git a/tests/eko/runner/__init__.py b/tests/eko/runner/__init__.py index c8ec5b854..0e3ea68c0 100644 --- a/tests/eko/runner/__init__.py +++ b/tests/eko/runner/__init__.py @@ -1,19 +1,21 @@ import numpy as np +from eko import basis_rotation as br + def check_shapes(o, txs, ixs, theory_card, operators_card): - tpids = len(o.bases.targetpids) - ipids = len(o.bases.inputpids) + tpids = len(br.flavor_basis_pids) + ipids = len(br.flavor_basis_pids) op_shape = (tpids, len(txs), ipids, len(ixs)) # check output = input np.testing.assert_allclose(o.xgrid.raw, operators_card.xgrid.raw) # targetgrid and inputgrid in the opcard are now ignored, we are testing this np.testing.assert_allclose( - o.bases.targetgrid.raw, + o.xgrid.raw, txs.raw, ) - np.testing.assert_allclose(o.bases.inputgrid.raw, ixs.raw) + np.testing.assert_allclose(o.xgrid.raw, ixs.raw) np.testing.assert_allclose(o.mu20, operators_card.mu20) # check available operators ~o.operators diff --git a/tests/eko/runner/conftest.py b/tests/eko/runner/conftest.py index 6c513e3eb..3b3bac0b3 100644 --- a/tests/eko/runner/conftest.py +++ b/tests/eko/runner/conftest.py @@ -4,6 +4,7 @@ import pytest from eko import EKO +from eko import basis_rotation as br from eko.io.items import Operator from eko.io.runcards import OperatorCard, TheoryCard from eko.runner import commons, recipes @@ -21,7 +22,7 @@ def neweko(theory_card: TheoryCard, operator_card: OperatorCard, tmp_path: Path) @pytest.fixture def identity(neweko: EKO): xs = len(neweko.xgrid.raw) - flavs = len(neweko.bases.pids) + flavs = len(br.flavor_basis_pids) return Operator(operator=np.eye(xs * flavs).reshape((xs, flavs, xs, flavs))) diff --git a/tests/eko/runner/test_legacy.py b/tests/eko/runner/test_legacy.py index 60395acc5..1828285c3 100644 --- a/tests/eko/runner/test_legacy.py +++ b/tests/eko/runner/test_legacy.py @@ -36,7 +36,7 @@ class FakeEM(enum.Enum): eko.runner.legacy.Runner(theory_card, operator_card, path=path) # MSbar scheme theory_card.heavy.masses_scheme = QuarkMassScheme.MSBAR - theory_card.couplings.num_flavs_ref = 5 + theory_card.couplings.ref = (91.0, 5) theory_card.heavy.masses.c.scale = 2 theory_card.heavy.masses.b.scale = 4.5 theory_card.heavy.masses.t.scale = 173.07 diff --git a/tests/eko/runner/test_operators.py b/tests/eko/runner/test_operators.py index 77811cf3a..7a8b4cdb7 100644 --- a/tests/eko/runner/test_operators.py +++ b/tests/eko/runner/test_operators.py @@ -6,8 +6,8 @@ def test_retrieve(ekoparts: EKO): - evhead, evop = next(iter(ekoparts.parts.cache.items())) - matchhead, matchop = next(iter(ekoparts.parts_matching.cache.items())) + evhead, _evop = next(iter(ekoparts.parts.cache.items())) + matchhead, _matchop = next(iter(ekoparts.parts_matching.cache.items())) els = _retrieve([evhead] * 5, ekoparts.parts, ekoparts.parts_matching) assert len(els) == 5 @@ -27,7 +27,7 @@ def test_join(identity: Operator): matrix product, but there not so many sensible rank-4 operators. """ - linear_size = np.product(identity.operator.shape[:2]) + linear_size = np.prod(identity.operator.shape[:2]) for n in range(1, 8, 3): res = join([identity for _ in range(n)]) assert res.error is None diff --git a/tests/eko/scale_variations/test_diff.py b/tests/eko/scale_variations/test_diff.py new file mode 100644 index 000000000..13cc4938f --- /dev/null +++ b/tests/eko/scale_variations/test_diff.py @@ -0,0 +1,182 @@ +"""Test ``ModSV=exponentiated`` kernel vs ``ModSV=expanded``. + +We test that the quantity :math:`ker_A / ker_B` for truncated solution, +is always higher order difference. + +For simplicity we do FFNS nf=4. +""" + +import numpy as np + +from eko import basis_rotation as br +from eko.beta import beta_qcd_as2, beta_qcd_as3 +from eko.couplings import CouplingEvolutionMethod, Couplings, CouplingsInfo +from eko.kernels import EvoMethods, non_singlet, singlet +from eko.quantities.heavy_quarks import QuarkMassScheme +from eko.scale_variations import expanded, exponentiated +from ekore.anomalous_dimensions.unpolarized.space_like import gamma_ns, gamma_singlet + +NF = 4 +Q02 = 1.65**2 +Q12 = 100**2 +EV_METHOD = EvoMethods.TRUNCATED + + +def compute_a_s(q2, order): + sc = Couplings( + couplings=CouplingsInfo( + alphas=0.1181, + alphaem=0.007496, + ref=(91.00, 4), + ), + order=order, + method=CouplingEvolutionMethod.EXPANDED, + masses=np.array([0.0, np.inf, np.inf]), + hqm_scheme=QuarkMassScheme.POLE, + thresholds_ratios=np.array([1.0, 1.0, 1.0]), + ) + # the multiplication for xif2 here it's done explicitly outside + return sc.a_s(scale_to=q2) + + +def scheme_diff_ns(g, a0, a1, L, order): + """:math:`ker_A / ker_B` for truncated non-singlet expansion.""" + + b0 = beta_qcd_as2(NF) + b1 = beta_qcd_as3(NF) + if order == (1, 0): + # series of (1.0 + b0 * L * a0) ** (g[0] / b0), L->0 + diff = 1 + a0 * g[0] * L + 1 / 2 * a0**2 * g[0] * (-b0 + g[0]) * L**2 + elif order == (2, 0): + # this term is formally 1 + as^2 + diff = ( + 1 + - (a1**2 * g[0] * L * (-b1 * g[0] + b0 * (g[1] + b0 * g[0] * L))) / b0**2 + + ( + (a0 * a1 * g[0] * L) + * (-2 * b1 * g[0] + b0 * (3 * b0 * g[0] * L + g[1] * 2)) + ) + / b0**2 + + (a0**2 * L / (2 * b0**5)) + * ( + +3 * b0**6 * g[0] * L + + b0**5 * (-3 * g[0] * g[0] * L + g[1] * 2) + + (2 * b0**3) * (+b1 * g[0] * (g[0])) + + b0**4 * (-2 * g[0] * g[1]) + ) + ) + return diff + + +def scheme_diff_s(g, a0, a1, L, order): + """:math:`ker_A / ker_B` for truncated singlet expansion.""" + + b0 = beta_qcd_as2(NF) + b1 = beta_qcd_as3(NF) + if order == (1, 0): + # series of exp(log(1.0 + b0 * L * a0) * g[0] / b0)[0], L->0 + diff = np.eye(2) + a0 * g[0] * L + 1 / 2 * a0**2 * g[0] @ (-b0 + g[0]) * L**2 + elif order == (2, 0): + # this term is formally 1 + as^2 + diff = ( + np.eye(2) + - (a1**2 * g[0] * L @ (-b1 * g[0] + b0 * (g[1] + b0 * g[0] * L))) / b0**2 + + ( + (a0 * a1 * g[0] * L) + @ (-2 * b1 * g[0] + b0 * (3 * b0 * g[0] * L + g[1] * 2)) + ) + / b0**2 + + (a0**2 * L / (2 * b0**5)) + * ( + +3 * b0**6 * g[0] * L + + b0**5 * (-3 * g[0] @ g[0] * L + g[1] * 2) + + (2 * b0**3) * (+b1 * g[0] @ (g[0])) + + b0**4 * (-2 * g[0] @ g[1]) + ) + ) + return diff + + +def test_scale_variation_a_vs_b(): + r"""Test ``ModSV=exponentiated`` kernel vs ``ModSV=expanded``.""" + + # let's use smaller scale variation to + # keep the expansions under control + for xif2 in [0.9, 1.1]: + L = np.log(xif2) + for order in [(1, 0), (2, 0)]: + # compute values of alphas + a0 = compute_a_s(Q02, order) + a1 = compute_a_s(Q12, order) + a0_b = a0 + a1_b = compute_a_s(Q12 * xif2, order) + a0_a = compute_a_s(Q02 * xif2, order) + a1_a = a1_b # for FFNS these 2 will coincide + for n in [2.0, 3.0, 10.0]: + # Non singlet kernels + gns = gamma_ns( + order, + br.non_singlet_pids_map["ns+"], + n, + NF, + n3lo_ad_variation=(0, 0, 0, 0, 0, 0, 0), + ) + + # build scheme B solution + ker_b = non_singlet.dispatcher( + order, EV_METHOD, gns, a1_b, a0_b, NF, ev_op_iterations=1 + ) + ker_b = ker_b * expanded.non_singlet_variation(gns, a1_b, order, NF, L) + + # build scheme A solution + gns_a = exponentiated.gamma_variation(gns.copy(), order, NF, L) + ker_a = non_singlet.dispatcher( + order, EV_METHOD, gns_a, a1_a, a0_a, NF, ev_op_iterations=1 + ) + + ns_diff = scheme_diff_ns(gns, a0, a1, L, order) + np.testing.assert_allclose( + ker_a / ker_b, + ns_diff, + err_msg=f"{L=},{order=},{n=},non-singlet", + rtol=2e-5 if order == (1, 0) else 3e-3, + ) + + # Singlet kernels + gs = gamma_singlet( + order, n, NF, n3lo_ad_variation=(0, 0, 0, 0, 0, 0, 0) + ) + + # build scheme B solution + ker_b = singlet.dispatcher( + order, + EV_METHOD, + gs, + a1_b, + a0_b, + NF, + ev_op_iterations=1, + ev_op_max_order=1, + ) + ker_b = expanded.singlet_variation(gs, a1_b, order, NF, L, 2) @ ker_b + + # build scheme A solution + gs_a = exponentiated.gamma_variation(gs.copy(), order, NF, L) + ker_a = singlet.dispatcher( + order, + EV_METHOD, + gs_a, + a1_a, + a0_a, + NF, + ev_op_iterations=1, + ev_op_max_order=1, + ) + + s_diff = scheme_diff_s(gs, a0, a1, L, order) + np.testing.assert_allclose( + np.diag(ker_a @ np.linalg.inv(ker_b)), + np.diag(s_diff), + err_msg=f"{L=},{order=},{n=},singlet", + rtol=2e-4 if order == (1, 0) else 9e-3, + ) diff --git a/tests/eko/scale_variations/test_expanded.py b/tests/eko/scale_variations/test_expanded.py index d85b8926a..309a87597 100644 --- a/tests/eko/scale_variations/test_expanded.py +++ b/tests/eko/scale_variations/test_expanded.py @@ -1,11 +1,34 @@ import numpy as np from eko import basis_rotation as br -from eko.beta import beta_qcd_as2, beta_qcd_as3 -from eko.kernels import non_singlet, singlet -from eko.scale_variations import Modes, expanded, exponentiated +from eko.couplings import CouplingEvolutionMethod, Couplings, CouplingsInfo +from eko.kernels import EvoMethods, non_singlet, singlet +from eko.quantities.heavy_quarks import QuarkMassScheme +from eko.scale_variations import Modes, expanded from ekore.anomalous_dimensions.unpolarized.space_like import gamma_ns, gamma_singlet +NF = 4 +Q02 = 1.65**2 +Q12 = 100**2 +EV_METHOD = EvoMethods.TRUNCATED + + +def compute_a_s(q2, order): + sc = Couplings( + couplings=CouplingsInfo( + alphas=0.1181, + alphaem=0.007496, + ref=(91.00, 4), + ), + order=order, + method=CouplingEvolutionMethod.EXPANDED, + masses=np.array([0.0, np.inf, np.inf]), + hqm_scheme=QuarkMassScheme.POLE, + thresholds_ratios=np.array([1.0, 1.0, 1.0]), + ) + # the multiplication for xif2 here it's done explicitly outside + return sc.a_s(scale_to=q2) + def test_modes(): assert Modes.expanded.name == "expanded" @@ -91,111 +114,80 @@ def test_valence_sv_dispacher_qed(): ) -def test_scale_variation_a_vs_b(): - r""" - Test ``ModSV=exponentiated`` kernel vs ``ModSV=expanded``. - We test that the quantity :math:`(ker_A - ker_B)/ker_{unv}` - - Note this is NOT the real difference between scheme expanded - and exponentiated since here we don't take into account the - shifts in path length and :math:`\alpha_s` values. - The real difference is always higher order. - """ - nf = 5 - n = 10 - a1 = 0.118 / (4 * np.pi) - a0 = 0.2 / (4 * np.pi) - method = "truncated" - - def scheme_diff(g, k, pto, is_singlet): - """ - :math:`(ker_A - ker_B)/ker_{unv}` for truncated expansion - Effects due to non commutativity are neglected thus, - the accuracy of singlet quantities is slightly worse. - """ - if pto[0] >= 2: - diff = -g[0] * k * a0 # - 2 * a1 * k * g[0] - # if pto[0] >= 3: - # b0 = beta_qcd_as2(nf) - # g02 = g[0] @ g[0] if is_singlet else g[0] ** 2 - # diff += ( - # -2 * a1**2 * g[1] * k - # + a0**2 * g[1] * k - # + a1**2 * b0 * g[0] * k**2 - # - 0.5 * a0**2 * b0 * g[0] * k**2 - # - a1 * a0 * g02 * k**2 - # + 0.5 * a0**2 * g02 * k**2 - # + a1**2 * g02 * k**2 - # ) - # if pto[0] >= 4: - # b1 = beta_qcd_as3(nf) - # g0g1 = g[0] @ g[1] if is_singlet else g[0] * g[1] - # g03 = g02 @ g[0] if is_singlet else g02 * g[0] - # diff += ( - # a0**3 * g[2] * k - # - 2 * a1**3 * g[2] * k - # - 1 / 2 * a0**3 * b1 * g[0] * k**2 - # + a1**3 * b1 * g[0] * k**2 - # - a0**3 * b0 * g[1] * k**2 - # + 2 * a1**3 * b0 * g[1] * k**2 - # + a0**3 * g0g1 * k**2 - # - a0**2 * a1 * g0g1 * k**2 - # - a0 * a1**2 * g0g1 * k**2 - # + 2 * a1**3 * g0g1 * k**2 - # + 1 / 3 * a0**3 * b0**2 * g[0] * k**3 - # - 2 / 3 * a1**3 * b0**2 * g[0] * k**3 - # - 1 / 2 * a0**3 * b0 * g02 * k**3 - # + 1 / 2 * a0**2 * a1 * b0 * g02 * k**3 - # + 1 / 2 * a0 * a1**2 * b0 * g02 * k**3 - # - a1**3 * b0 * g02 * k**3 - # + 1 / 6 * a0**3 * g03 * k**3 - # - 1 / 2 * a0**2 * a1 * g03 * k**3 - # + 1 / 2 * a0 * a1**2 * g03 * k**3 - # - 1 / 3 * a1**3 * g03 * k**3 - # ) - return diff - - for L in [np.log(0.5), np.log(2)]: - # for order in [(2, 0), (3, 0), (4, 0)]: - for order in [(2, 0)]: - # Non singlet kernels - gns = gamma_ns( - order, - br.non_singlet_pids_map["ns+"], - n, - nf, - n3lo_ad_variation=(0, 0, 0, 0, 0, 0, 0), - ) - ker = non_singlet.dispatcher( - order, method, gns, a1, a0, nf, ev_op_iterations=1 - ) - gns_a = exponentiated.gamma_variation(gns.copy(), order, nf, L) - ker_a = non_singlet.dispatcher( - order, method, gns_a, a1, a0, nf, ev_op_iterations=1 - ) - ker_b = ker * expanded.non_singlet_variation(gns, a1, order, nf, L) - ns_diff = scheme_diff(gns, L, order, False) +def test_expanded_is_linear(): + r"""Test is linear.""" + for order in [(1, 0), (2, 0), (3, 0), (4, 0)]: + for n in [2.0, 3.0, 10.0]: + rel_err_ns = [] + rel_err_s = [] + for L in [0.3, 0.5, 0.7]: + xif2 = np.exp(L) + # compute values of alphas + a0 = compute_a_s(Q02, order) + a1 = compute_a_s(Q12, order) + a1_b = compute_a_s(Q12 * xif2, order) + # Non singlet kernels + gns = gamma_ns( + order, + br.non_singlet_pids_map["ns+"], + n, + NF, + n3lo_ad_variation=(0, 0, 0, 0, 0, 0, 0), + ) + + # build scheme B solution + ker_b = non_singlet.dispatcher( + order, EV_METHOD, gns, a1, a0, NF, ev_op_iterations=1 + ) + sv_b = non_singlet.dispatcher( + order, EV_METHOD, gns, a1_b, a0, NF, ev_op_iterations=1 + ) + sv_b = sv_b * expanded.non_singlet_variation(gns, a1_b, order, NF, L) + + rel_err_ns.append(sv_b / ker_b) + + # Singlet kernels + gs = gamma_singlet( + order, n, NF, n3lo_ad_variation=(0, 0, 0, 0, 0, 0, 0) + ) + + # build scheme B solution + ker_b = singlet.dispatcher( + order, + EV_METHOD, + gs, + a1, + a0, + NF, + ev_op_iterations=1, + ev_op_max_order=1, + ) + sv_b = singlet.dispatcher( + order, + EV_METHOD, + gs, + a1_b, + a0, + NF, + ev_op_iterations=1, + ev_op_max_order=1, + ) + sv_b = expanded.singlet_variation(gs, a1_b, order, NF, L, 2) @ sv_b + rel_err_s.append(sv_b @ np.linalg.inv(ker_b)) + + # there must be something + for err in rel_err_ns: + assert np.abs(err) != 1.0 + for err in np.array(rel_err_s).flatten(): + assert np.abs(err) != 1.0 + # error has to increase np.testing.assert_allclose( - (ker_a - ker_b) / ker, - ns_diff, - atol=1e-3, - err_msg=f"L={L},order={order},non-singlet", - ) - - # Singlet kernels - gs = gamma_singlet(order, n, nf, n3lo_ad_variation=(0, 0, 0, 0, 0, 0, 0)) - ker = singlet.dispatcher( - order, method, gs, a1, a0, nf, ev_op_iterations=1, ev_op_max_order=1 - ) - gs_a = exponentiated.gamma_variation(gs.copy(), order, nf, L) - ker_a = singlet.dispatcher( - order, method, gs_a, a1, a0, nf, ev_op_iterations=1, ev_op_max_order=1 + rel_err_ns, + sorted(rel_err_ns, reverse=True), + err_msg=f"{order=},{n=},non-singlet", ) - ker_b = ker @ expanded.singlet_variation(gs, a1, order, nf, L, 2) - s_diff = scheme_diff(gs, L, order, True) np.testing.assert_allclose( - (ker_a - ker_b) @ np.linalg.inv(ker), - s_diff, - atol=5e-3, - err_msg=f"L={L},order={order},singlet", + rel_err_s, + sorted(rel_err_s, key=np.max, reverse=True), + err_msg=f"{order=},{n=},singlet", ) diff --git a/tests/eko/test_beta.py b/tests/eko/test_beta.py index 682c79f57..8fcdd6931 100644 --- a/tests/eko/test_beta.py +++ b/tests/eko/test_beta.py @@ -2,6 +2,7 @@ This module tests the implemented beta functions and the value of alpha_s for different orders. """ + import numpy as np import pytest diff --git a/tests/eko/test_couplings.py b/tests/eko/test_couplings.py index 62110da16..9b68d308b 100644 --- a/tests/eko/test_couplings.py +++ b/tests/eko/test_couplings.py @@ -2,6 +2,7 @@ This module tests the implemented beta functions and the value of alpha_s for different orders. """ + import copy import enum @@ -53,9 +54,7 @@ def test_init(self): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=None, - max_num_flavs=6, + ref=(muref, 5), ) ) order = (1, 0) @@ -108,7 +107,7 @@ def test_init(self): ) with pytest.raises(ValueError): coup3 = copy.deepcopy(couplings) - coup3.scale = 0 + coup3.ref = (0.0, 5) Couplings( coup3, order, @@ -152,18 +151,17 @@ def test_ref(self): (0, np.inf, np.inf), (2, 4, 175), ] + nfrefs = (3, 4, 5) alpharef = (0.118, 0.00781) muref = 91.0 - couplings = CouplingsInfo.from_dict( - dict( - alphas=alpharef[0], - alphaem=alpharef[1], - scale=muref, - num_flavs_ref=None, - max_num_flavs=6, + for thresh_setup, nfref in zip(thresh_setups, nfrefs): + couplings = CouplingsInfo.from_dict( + dict( + alphas=alpharef[0], + alphaem=alpharef[1], + ref=(muref, nfref), + ) ) - ) - for thresh_setup in thresh_setups: for order_s in [1, 2, 3, 4]: for order_em in [0, 1, 2]: for evmod in CouplingEvolutionMethod: @@ -194,9 +192,7 @@ def test_ref_copy_e841b0dfdee2f31d9ccc1ecee4d9d1a6f6624313(self): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=3, # reference nf is needed to force the matching - max_num_flavs=6, + ref=(muref, 3), # reference nf is needed to force the matching ) ) sc = Couplings( @@ -220,9 +216,10 @@ def test_exact(self): (0, np.inf, np.inf), (2, 4, 175), ] + nfrefs = (3, 4, 5) alpharef = np.array([0.118, 0.00781]) muref = 91.0 - for thresh_setup in thresh_setups: + for thresh_setup, nfref in zip(thresh_setups, nfrefs): for qcd in range(1, 4 + 1): for qed in range(2 + 1): for em_running in [ @@ -234,9 +231,7 @@ def test_exact(self): dict( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=None, - max_num_flavs=6, + ref=(muref, nfref), em_running=em_running, ) ) @@ -297,9 +292,7 @@ def benchmark_expanded_n3lo(self): couplings = CouplingsInfo( alphas=alpharef[0], alphaem=alpharef[1], - scale=muref, - num_flavs_ref=None, - max_num_flavs=6, + ref=(muref, 5), ) m2c = 2 m2b = 25 diff --git a/tests/eko/test_gamma.py b/tests/eko/test_gamma.py index 3e9533b89..dfa8f069f 100644 --- a/tests/eko/test_gamma.py +++ b/tests/eko/test_gamma.py @@ -1,6 +1,7 @@ """ This module tests the implemented gamma functions """ + import numpy as np import pytest diff --git a/tests/eko/test_matchings.py b/tests/eko/test_matchings.py index 36a540f3f..12934789d 100644 --- a/tests/eko/test_matchings.py +++ b/tests/eko/test_matchings.py @@ -1,4 +1,5 @@ """Tests for the threshold class""" + from dataclasses import astuple import numpy as np diff --git a/tests/eko/test_msbar_masses.py b/tests/eko/test_msbar_masses.py index b0c102ef8..25718e962 100644 --- a/tests/eko/test_msbar_masses.py +++ b/tests/eko/test_msbar_masses.py @@ -1,4 +1,5 @@ """Tests for the threshold class.""" + import numpy as np import pytest @@ -15,9 +16,8 @@ def theory_card(theory_card: TheoryCard): th = theory_card th.order = (3, 0) th.couplings.alphas = 0.1180 - th.couplings.scale = 91.0 th.couplings.alphaem = 0.00781 - th.couplings.num_flavs_ref = 5 + th.couplings.ref = (91.0, 5) th.heavy.masses = HeavyQuarkMasses( [QuarkMassRef(val) for val in [(2.0, 2.1), (4.0, 4.1), (175.0, 174.9)]] ) diff --git a/tests/eko/test_quantities.py b/tests/eko/test_quantities.py index 0c2628b30..d3c412a25 100644 --- a/tests/eko/test_quantities.py +++ b/tests/eko/test_quantities.py @@ -33,9 +33,6 @@ def test_HeavyQuarks(): def test_HeavyInfo(): i = hq.HeavyInfo( - num_flavs_init=4, - num_flavs_max_pdf=6, - intrinsic_flavors=[4, 5], masses=hq.HeavyQuarkMasses( [ hq.QuarkMassRef([2.0, nan]), diff --git a/tests/ekobox/test_apply.py b/tests/ekobox/test_apply.py index 8fa23548f..70eb74adc 100644 --- a/tests/ekobox/test_apply.py +++ b/tests/ekobox/test_apply.py @@ -1,5 +1,6 @@ import numpy as np +from eko import basis_rotation as br from ekobox import apply from tests.conftest import EKOFactory @@ -12,13 +13,13 @@ def test_apply(self, eko_factory: EKOFactory, fake_pdf): pdf_grid = apply.apply_pdf(eko, fake_pdf) assert len(pdf_grid) == len(eko.evolgrid) pdfs = pdf_grid[ep_out]["pdfs"] - assert list(pdfs.keys()) == list(eko.bases.targetpids) + assert list(pdfs.keys()) == list(br.flavor_basis_pids) # rotate to target_grid target_grid = [0.75] pdf_grid = apply.apply_pdf(eko, fake_pdf, target_grid) assert len(pdf_grid) == 1 pdfs = pdf_grid[ep_out]["pdfs"] - assert list(pdfs.keys()) == list(eko.bases.targetpids) + assert list(pdfs.keys()) == list(br.flavor_basis_pids) def test_apply_flavor(self, eko_factory: EKOFactory, fake_pdf, monkeypatch): eko = eko_factory.get() @@ -27,12 +28,8 @@ def test_apply_flavor(self, eko_factory: EKOFactory, fake_pdf, monkeypatch): monkeypatch.setattr( "eko.basis_rotation.rotate_flavor_to_evolution", np.ones((14, 14)) ) - monkeypatch.setattr( - "eko.basis_rotation.flavor_basis_pids", - eko.bases.targetpids, - ) fake_evol_basis = tuple( - ["a", "b"] + [str(x) for x in range(len(eko.bases.pids) - 2)] + ["a", "b"] + [str(x) for x in range(len(br.flavor_basis_pids) - 2)] ) monkeypatch.setattr("eko.basis_rotation.evol_basis", fake_evol_basis) pdf_grid = apply.apply_pdf(eko, fake_pdf, rotate_to_evolution_basis=True) diff --git a/tests/ekobox/test_cards.py b/tests/ekobox/test_cards.py index 1a35e137e..00ef0e4c3 100644 --- a/tests/ekobox/test_cards.py +++ b/tests/ekobox/test_cards.py @@ -10,14 +10,14 @@ def test_generate_ocard(): mu0 = 1.65 mugrid = [(10.0, 6), (100.0, 5)] op = cards.example.operator() - op.mu0 = mu0 + op.init = (mu0, 4) op.mugrid = mugrid assert pytest.approx(op.mugrid) == mugrid assert pytest.approx(op.mu2grid) == np.array([mu**2 for mu, _ in mugrid]) assert op.configs.interpolation_polynomial_degree == 4 mugrid1 = [100.0, 5] op = cards.example.operator() - op.mu0 = mu0 + op.init = (mu0, 4) op.mugrid = mugrid1 op.configs.interpolation_polynomial_degree = 2 op.configs.interpolation_is_log = False @@ -35,7 +35,7 @@ def test_dump_load_op_card(tmp_path, cd): path1 = tmp_path / "debug_op.yaml" path2 = tmp_path / "debug_op_two.yaml" op = cards.example.operator() - op.mu0 = mu0 + op.init = (mu0, 4) cards.dump(op.raw, path1) cards.dump(op.raw, path2) op_loaded = cards.load(path1) @@ -52,7 +52,7 @@ def test_generate_theory_card(): assert theory.order[0] == 2 rawt = cards.example.raw_theory() assert isinstance(rawt, dict) - assert theory.heavy.num_flavs_init == rawt["heavy"]["num_flavs_init"] + assert theory.heavy.masses.c[0] == rawt["heavy"]["masses"][0][0] def containsnan(obj) -> bool: diff --git a/tests/ekobox/test_evol_pdf.py b/tests/ekobox/test_evol_pdf.py index 54bce6623..7d788277b 100644 --- a/tests/ekobox/test_evol_pdf.py +++ b/tests/ekobox/test_evol_pdf.py @@ -1,4 +1,5 @@ import numpy as np +import pytest from banana import toy import eko @@ -11,7 +12,7 @@ def init_cards(): op = cards.example.operator() - op.mu0 = 1.65 + op.init = (1.65, 4) op.xgrid = XGrid([0.1, 0.5, 1.0]) op.configs.interpolation_polynomial_degree = 1 theory = cards.example.theory() @@ -50,6 +51,21 @@ def test_evolve_pdfs_dump_path(fake_lhapdf, cd): assert p.exists() +def test_evolve_pdfs_bad_scales(fake_lhapdf, cd): + """Bad scale configurations.""" + theory, op = init_cards() + n = "test_evolve_pdfs_bad_scales" + op = cards.example.operator() + op.mugrid = [(5.0, 3), (15.0, 4), (10.0, 5), (100.0, 5)] + with pytest.raises(ValueError, match="is bigger"): + with cd(fake_lhapdf): + ev_p.evolve_pdfs([toy.mkPDF("", 0)], theory, op, name=n, path=fake_lhapdf) + op.mugrid = [(5.0, 3), (10.0, 3), (10.0, 4), (15.0, 4), (10.0, 5)] + with pytest.raises(ValueError, match="is bigger"): + with cd(fake_lhapdf): + ev_p.evolve_pdfs([toy.mkPDF("", 0)], theory, op, name=n, path=fake_lhapdf) + + def test_evolve_pdfs_dump_file(fake_lhapdf, cd): theory, op = init_cards() n = "test_evolve_pdfs_dump_file" diff --git a/tests/ekobox/test_info_file.py b/tests/ekobox/test_info_file.py index 64af8eb93..62df7d739 100644 --- a/tests/ekobox/test_info_file.py +++ b/tests/ekobox/test_info_file.py @@ -10,7 +10,7 @@ def test_build(): theory.order = (2, 0) theory.couplings.alphas = 0.2 op = cards.example.operator() - op.mu0 = 1.0 + op.init = (1.0, 3) op.mugrid = [(10.0, 5), (100.0, 5)] info = info_file.build( theory, op, 4, info_update={"SetDesc": "Prova", "NewArg": 15.3, "MTop": 1.0} @@ -23,3 +23,27 @@ def test_build(): np.testing.assert_allclose(info["QMin"], math.sqrt(op.mu2grid[0]), rtol=1e-5) assert info["XMin"] == op.xgrid.raw[0] assert info["XMax"] == op.xgrid.raw[-1] == 1.0 + + +def test_build_alphas_good(): + """Good configurations.""" + theory = cards.example.theory() + theory.order = (2, 0) + theory.couplings.alphas = 0.2 + op = cards.example.operator() + op.mu0 = 1.0 + # base case + op.mugrid = [(100.0, 5), (10.0, 5)] + info = info_file.build_alphas(theory, op) + assert len(info["AlphaS_Vals"]) == 2 + np.testing.assert_allclose(info["AlphaS_Qs"], [10.0, 100.0]) + # several nf + op.mugrid = [(5.0, 4), (10.0, 5), (1.0, 3), (5.0, 3), (10.0, 5), (100.0, 5)] + info = info_file.build_alphas(theory, op) + assert len(info["AlphaS_Vals"]) == 6 + np.testing.assert_allclose(info["AlphaS_Qs"], [1.0, 5.0, 5.0, 10.0, 10.0, 100.0]) + # several nf with gap + op.mugrid = [(1.0, 3), (10.0, 3), (10.0, 5), (100.0, 5)] + info = info_file.build_alphas(theory, op) + assert len(info["AlphaS_Vals"]) == 4 + np.testing.assert_allclose(info["AlphaS_Qs"], [1.0, 10.0, 10.0, 100.0]) diff --git a/tests/ekobox/test_utils.py b/tests/ekobox/test_utils.py index 557db679c..1233d1d91 100644 --- a/tests/ekobox/test_utils.py +++ b/tests/ekobox/test_utils.py @@ -16,10 +16,9 @@ def test_ekos_product(tmp_path): theory = cards.example.theory() theory.order = (1, 0) - theory.heavy.num_flavs_init = 5 op1 = cards.example.operator() - op1.mu0 = mu01 + op1.init = (mu01, 5) op1.mugrid = mugrid1 op1.xgrid = xgrid op1.configs.interpolation_polynomial_degree = 1 @@ -28,13 +27,13 @@ def test_ekos_product(tmp_path): mugrid2 = [(8.0, 5), (10.0, 5), (12.0, 5)] op2 = cards.example.operator() - op2.mu0 = mu0 + op2.init = (mu0, 5) op2.mugrid = mugrid2 op2.xgrid = xgrid op2.configs.interpolation_polynomial_degree = 1 op_err = copy.deepcopy(op2) - op_err.mu0 = mu01 + op_err.init = (mu01, 5) mu2first = (mugrid2[0][0] ** 2, mugrid2[0][1]) diff --git a/tests/ekomark/data/__init__.py b/tests/ekomark/data/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ekomark/data/test_init.py b/tests/ekomark/data/test_init.py new file mode 100644 index 000000000..278a06181 --- /dev/null +++ b/tests/ekomark/data/test_init.py @@ -0,0 +1,96 @@ +import copy + +import numpy as np +import pytest +from banana.data.theories import default_card as theory_card + +from eko.io import runcards as rc +from ekomark.data import update_runcards +from ekomark.data.operators import default_card as operator_card + +from ...eko.io.test_runcards import check_dumpable + + +def test_runcards_opcard(): + # check conversion + tc = copy.deepcopy(theory_card) + oc = copy.deepcopy(operator_card) + tc["Q0"] = 2.0 + # mugrid + oc["mugrid"] = [2.0, 10.0] + _nt, no = update_runcards(tc, oc) + assert isinstance(no, rc.OperatorCard) + assert len(no.evolgrid) == len(oc["mugrid"]) + assert len(no.mu2grid) == len(no.evolgrid) + assert no.evolgrid[0][-1] == 4 + assert no.evolgrid[1][-1] == 5 + np.testing.assert_allclose(no.init[0], tc["Q0"]) + np.testing.assert_allclose(no.mu20, tc["Q0"] ** 2.0) + assert len(no.pids) == 14 + check_dumpable(no) + del oc["mugrid"] + # or mu2grid + oc["mu2grid"] = [9.0, 30.0, 32.0] + _nt, no = update_runcards(tc, oc) + assert isinstance(no, rc.OperatorCard) + assert len(no.evolgrid) == len(oc["mu2grid"]) + assert len(no.mu2grid) == len(no.evolgrid) + assert no.evolgrid[0][-1] == 4 + assert no.evolgrid[1][-1] == 5 + assert no.evolgrid[2][-1] == 5 + check_dumpable(no) + del oc["mu2grid"] + # or Q2grid + oc["Q2grid"] = [15.0, 130.0, 140.0, 1e5] + _nt, no = update_runcards(tc, oc) + assert isinstance(no, rc.OperatorCard) + assert len(no.evolgrid) == len(oc["Q2grid"]) + assert len(no.mu2grid) == len(no.evolgrid) + assert no.evolgrid[0][-1] == 4 + assert no.evolgrid[1][-1] == 5 + assert no.evolgrid[2][-1] == 5 + assert no.evolgrid[3][-1] == 6 + check_dumpable(no) + + +def test_runcards_ekomark(): + # check conversion + tc = copy.deepcopy(theory_card) + oc = copy.deepcopy(operator_card) + nt, no = update_runcards(tc, oc) + assert isinstance(nt, rc.TheoryCard) + assert isinstance(no, rc.OperatorCard) + # check is idempotent + nnt, nno = update_runcards(nt, no) + assert nnt == nt + assert nno == no + + +def test_runcards_quarkmass(): + tc = copy.deepcopy(theory_card) + tc["nfref"] = 5 + tc["IC"] = 1 + oc = copy.deepcopy(operator_card) + nt, no = update_runcards(tc, oc) + for _, scale in nt.heavy.masses: + assert np.isnan(scale) + m2s = rc.masses(nt, no.configs.evolution_method) + raw = rc.Legacy.heavies("m%s", tc) + raw2 = np.power(raw, 2.0) + np.testing.assert_allclose(m2s, raw2) + tc["HQ"] = "MSBAR" + tc["Qmc"] = raw[0] * 1.1 + tc["Qmb"] = raw[1] * 1.1 + tc["Qmt"] = raw[2] * 0.9 + nt, no = update_runcards(tc, oc) + for _, scale in nt.heavy.masses: + assert not np.isnan(scale) + m2s = rc.masses(nt, no.configs.evolution_method) + for m1, m2 in zip(m2s, raw2): + assert not np.isclose(m1, m2) + tc["HQ"] = "Blub" + with pytest.raises(ValueError, match="mass scheme"): + _nt, _no = update_runcards(tc, oc) + nt.heavy.masses_scheme = "Bla" + with pytest.raises(ValueError, match="mass scheme"): + _ms = rc.masses(nt, no.configs.evolution_method) diff --git a/tests/ekore/anomalous_dimensions/polarized/space_like/test_ad_as2.py b/tests/ekore/anomalous_dimensions/polarized/space_like/test_ad_as2.py index 743bae92d..b77fd7a83 100755 --- a/tests/ekore/anomalous_dimensions/polarized/space_like/test_ad_as2.py +++ b/tests/ekore/anomalous_dimensions/polarized/space_like/test_ad_as2.py @@ -32,10 +32,7 @@ def test_qg_momentum(): cache = harmonics.cache.reset() np.testing.assert_allclose( -as2.gamma_qg(N, nf, cache), - 4 - * nf - * (0.574074 * CF - 2 * CA * (-7 / 18 + 1 / 6 * (5 - np.pi**2 / 3))) - * TR, + 4 * nf * (0.574074 * CF - 2 * CA * (-7 / 18 + 1 / 6 * (5 - np.pi**2 / 3))) * TR, ) @@ -58,6 +55,5 @@ def test_gg_momentum(): cache = harmonics.cache.reset() np.testing.assert_almost_equal( -as2.gamma_gg(N, nf, cache), - 4 - * (-1.7537256813471833 * CA**2 + ((29 * CA) / 27 - (28 * CF) / 27) * nf * TR), + 4 * (-1.7537256813471833 * CA**2 + ((29 * CA) / 27 - (28 * CF) / 27) * nf * TR), ) diff --git a/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py index 13562cd61..7eccd27c0 100644 --- a/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py @@ -18,7 +18,7 @@ n3lo_vars_dict = { "gg": 19, - "gq": 21, + "gq": 15, "qg": 15, "qq": 6, } @@ -132,7 +132,7 @@ def test_momentum_conservation(): np.testing.assert_allclose( gnsp.gamma_nsp_nf0(N, sx_cache) + g_gq[:, 0], 0, - atol=2e-10, + atol=1e-9, ) np.testing.assert_allclose( g_gg[:, 0], diff --git a/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4_fhmv.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4_fhmv.py index 8bef494c7..a6671e3b2 100644 --- a/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4_fhmv.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4_fhmv.py @@ -45,7 +45,7 @@ def test_momentum_conservation(): # total np.testing.assert_allclose( g_singlet[:, 0, 0] + g_singlet[:, 1, 0], - [0.08617, 0.220242, -0.047901], + [0.053441, 0.225674, -0.118792], atol=2e-5, ) np.testing.assert_allclose( @@ -190,7 +190,7 @@ def gq3_moment(N, nf): np.testing.assert_allclose( ggq.gamma_gq(N, nf, cache, variation), gq3_moment(N, nf), - rtol=2e-4, + rtol=4e-4, ) with pytest.raises(NotImplementedError): diff --git a/tests/ekore/operator_matrix_elements/polarized/space_like/test_nnlo.py b/tests/ekore/operator_matrix_elements/polarized/space_like/test_nnlo.py index cd0c507cc..c107aff89 100644 --- a/tests/ekore/operator_matrix_elements/polarized/space_like/test_nnlo.py +++ b/tests/ekore/operator_matrix_elements/polarized/space_like/test_nnlo.py @@ -27,18 +27,18 @@ def test_quark_number_conservation(): def test_hg(): refs = { 0: [ - -242.3869306886845, - -480.6122566782359, - -814.6150038529145, - -1244.9445223204148, - -1771.5995558739958, + -14.120648885210752, + -15.093091588201201, + -14.014668171450229, + -12.815826533022285, + -11.761139164575077, ], 10: [ - -21.21409118251165, - -295.28287396218656, - -664.653836052461, - -1121.4595082763883, - -1667.8336593381266, + 207.0521906209621, + 170.2362911278482, + 135.9464996290033, + 110.6691875110041, + 92.0047573712939, ], } for L, vals in refs.items(): diff --git a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_as3.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_as3.py index 2afd57d23..efc7cb277 100644 --- a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_as3.py +++ b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_as3.py @@ -26,7 +26,6 @@ def test_A_3(): N = 2.0 sx_cache = c.reset() # The accuracy of this test depends on the approximation of aHg3. - # which is not fully available. atol = 2e-4 if L == 0 else 2e-3 np.testing.assert_allclose( as3.A_gg(N, sx_cache, nf, L) @@ -123,18 +122,18 @@ def test_Blumlein_3(): } ref_val_a_Hg = { 0: [ - -99.16581867356965, - -676.0759818186247, - -768.6183629349141, - -789.7519719852811, - -414.2873373741821, + -99.16581867357172, + -676.0759818186266, + -768.6183629349151, + -789.751971985281, + -453.0949190997498, ], 10: [ - -99.16581867356965, - -676.0759818186247, - -768.6183629349141, - -789.7519719852811, - -414.2873373741821, + -99.16581867357172, + -676.0759818186266, + -768.6183629349151, + -789.751971985281, + -453.0949190997498, ], } ref_val_Hq = { @@ -197,7 +196,7 @@ def test_Blumlein_3(): aS3 = A_singlet(N, sx_cache, nf, L) np.testing.assert_allclose( - aS3[0, 0], ref_val_gg[L][idx] + ref_val_a_gg[L][idx], rtol=3e-6 + aS3[0, 0], ref_val_gg[L][idx] + ref_val_a_gg[L][idx], rtol=9e-6 ) np.testing.assert_allclose(aS3[0, 1], ref_val_gq[L][idx], rtol=2e-6) @@ -209,9 +208,9 @@ def test_Blumlein_3(): np.testing.assert_allclose( aS3[2, 1], ref_val_Hq[L][idx], rtol=2e-5, atol=2e-6 ) - # np.testing.assert_allclose( - # aS3[1, 1], ref_val_qqNS[L][idx] + ref_val_qqPS[L][idx], rtol=2e-6 - # ) + np.testing.assert_allclose( + aS3[1, 1], ref_val_qqNS[L][idx] + ref_val_qqPS[L][idx], rtol=2e-6 + ) # Here we test the critical parts for idx, N in enumerate([2.0, 4.0, 6.0, 10.0, 100.0]): From 009b4c9ff33fd21055833106f932bfd0c4dc882b Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 9 Aug 2024 12:46:26 +0300 Subject: [PATCH 67/67] Fix docstring of EKO.load --- src/eko/io/struct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eko/io/struct.py b/src/eko/io/struct.py index 3d332e8af..9ee1b73f9 100644 --- a/src/eko/io/struct.py +++ b/src/eko/io/struct.py @@ -340,7 +340,7 @@ def load(cls, path: Path): Note ---- - No archive path is assigned to the :cls:`EKO` object, setting its + No archive path is assigned to the :class:`EKO` object, setting its :attr:`EKO.access.path` to `None`. If you want to properly load from an archive, use the :meth:`read` constructor.