diff --git a/.gitignore b/.gitignore
index 6b68b80ca..14b79c3d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,6 @@ __pycache__/
ml_peg/app/data/*
!ml_peg/app/data/onboarding/
certs/
+ml_peg/calcs/surfaces/copper_water_interface/data/
+ml_peg/calcs/aqueous_solutions/bulk_water/data/
+ml_peg/calcs/aqueous_solutions/ice/data/
diff --git a/docs/source/tutorials/python/adding_benchmark.ipynb b/docs/source/tutorials/python/adding_benchmark.ipynb
index 783ea9da5..6d10f2911 100644
--- a/docs/source/tutorials/python/adding_benchmark.ipynb
+++ b/docs/source/tutorials/python/adding_benchmark.ipynb
@@ -748,7 +748,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"id": "87afda7e",
"metadata": {},
"outputs": [],
@@ -816,7 +816,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "6069c970",
"metadata": {},
"outputs": [],
@@ -864,7 +864,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"id": "c729e223",
"metadata": {},
"outputs": [],
@@ -913,19 +913,62 @@
"execution_count": null,
"id": "17c9092f",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
- "if __name__ == \"__main__\":\n",
- " # Create Dash app\n",
- " full_app = Dash(__name__, assets_folder=DATA_PATH.parent.parent)\n",
"\n",
- " # Construct layout and register callbacks\n",
- " x23_app = get_app()\n",
- " full_app.layout = x23_app.layout\n",
- " x23_app.register_callbacks()\n",
+ "# Create Dash app\n",
+ "full_app = Dash(__name__, assets_folder=DATA_PATH.parent.parent)\n",
"\n",
- " # Run app\n",
- " full_app.run(port=8055, debug=True)"
+ "# Construct layout and register callbacks\n",
+ "x23_app = get_app()\n",
+ "full_app.layout = x23_app.layout\n",
+ "x23_app.register_callbacks()\n",
+ "\n",
+ "# Run app\n",
+ "full_app.run(port=8055, debug=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "21af9ad5",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'cu-cu'"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "'Cu-Cu'.lower()"
]
},
{
@@ -952,11 +995,48 @@
"\n",
"You may also find it useful to refer to some [exemplar pull requests](https://github.com/ddmms/ml-peg/pulls?q=is%3Apr+label%3A%22example+benchmark+addition%22+), incuding examples of [data-only additions](https://github.com/ddmms/ml-peg/pulls?q=+is%3Apr+label%3A%22data+only%22+)."
]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2c931da5",
+ "metadata": {},
+ "source": [
+ "#Remote\n",
+ "ml_peg app --category surfaces --port 8060\n",
+ "\n",
+ "#Local\n",
+ "ssh -N -L 8061:localhost:8060 fast6\n",
+ "http://0.0.0.0:8060/"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2523f3ad",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#TODO\n",
+ "#Scatter RDF Score\n",
+ "#Plot RDF after scatter\n",
+ "#Plot RDF error after scatter\n",
+ "#Switch to bar plot\n",
+ "#Add VDOS\n",
+ "#Add VACF\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "9ebe0a48",
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
"kernelspec": {
- "display_name": "ml-peg (3.12.8)",
+ "display_name": "ml-peg",
"language": "python",
"name": "python3"
},
@@ -970,7 +1050,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.12.8"
+ "version": "3.12.3"
}
},
"nbformat": 4,
diff --git a/et --soft HEAD~1 b/et --soft HEAD~1
new file mode 100644
index 000000000..150ab5bb6
--- /dev/null
+++ b/et --soft HEAD~1
@@ -0,0 +1,29 @@
+[33mcommit 7d8bfdcb3d52f89081200dcdf300788b96edc5d3[m
+Author: IsaacParker30
+Date: Tue Feb 10 20:28:45 2026 +0000
+
+ clean data
+
+ ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface.zip | Bin [31m1122690031[m -> [32m0[m bytes
+ ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/init.pdb | 618 [31m--------------------------------------------[m
+ ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/rdf_reference.pkl | Bin [31m14970[m -> [32m0[m bytes
+ .../calcs/surfaces/copper_water_interface/data/copper_water_interface/ref_dipole_data.npy | Bin [31m251520[m -> [32m0[m bytes
+ .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vacf_reference.pkl | Bin [31m1039681[m -> [32m0[m bytes
+ .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vdos_reference.pkl | Bin [31m96450[m -> [32m0[m bytes
+ ml_peg/calcs/surfaces/copper_water_interface/data/old-cwi.zip | Bin [31m637519881[m -> [32m0[m bytes
+ 7 files changed, 618 deletions(-)
+
+[33mcommit b410110af654a7165bfdd67e20e9494c2cec410e[m
+Author: IsaacParker30
+Date: Tue Feb 10 20:26:17 2026 +0000
+
+ added core functionality with correct liniting
+
+ ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface.zip | Bin [31m0[m -> [32m1122690031[m bytes
+ ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/init.pdb | 618 [32m++++++++++++++++++++++++++++++++++++++++++++[m
+ ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/rdf_reference.pkl | Bin [31m0[m -> [32m14970[m bytes
+ .../calcs/surfaces/copper_water_interface/data/copper_water_interface/ref_dipole_data.npy | Bin [31m0[m -> [32m251520[m bytes
+ .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vacf_reference.pkl | Bin [31m0[m -> [32m1039681[m bytes
+ .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vdos_reference.pkl | Bin [31m0[m -> [32m96450[m bytes
+ ml_peg/calcs/surfaces/copper_water_interface/data/old-cwi.zip | Bin [31m0[m -> [32m637519881[m bytes
+ 7 files changed, 618 insertions(+)
diff --git a/ml_peg/analysis/aqueous_solutions/bulk_water/aml.py b/ml_peg/analysis/aqueous_solutions/bulk_water/aml.py
new file mode 100644
index 000000000..d9722aba4
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/bulk_water/aml.py
@@ -0,0 +1,918 @@
+"""Analysis module for bulk water. Upon usage cite Schran et al, PNAS, 2021."""
+
+from __future__ import annotations
+
+import pickle
+
+from ase.io import read
+import matplotlib.pyplot as plt
+import mdtraj as mdt
+import numpy as np
+from scipy import signal
+
+
+def _acfs_to_spectra(
+ acfs: np.ndarray,
+ nw: int,
+ npad: int = 0,
+ d: float = 1.0,
+ f_w: callable = np.hanning,
+) -> tuple[np.ndarray, np.ndarray]:
+ """
+ Calculate spectra from autocorrelation functions using FFT.
+
+ Optionally processes multiple spectra at the same time. In that case,
+ `acfs` is a 2D array of shape number of ACFs by length of ACFs. This is a
+ low-level function, use `get_spectra` for a more convenient interface.
+
+ Parameters
+ ----------
+ acfs
+ Array, 1D or 2D, symmetric full ACFs.
+ nw
+ One-sided number of points of ACF window.
+ npad
+ One-sided number of additional padding zeros. Default is 0.
+ d
+ Real-space step. Default is 1.0.
+ f_w
+ Function to evaluate the double-sided symmetric window. Default is np.hanning.
+
+ Returns
+ -------
+ tuple
+ Frequency and intensity arrays.
+ """
+ # Make sure we're processing a 2D array.
+ ndim = len(acfs.shape)
+ if ndim == 1:
+ acfs = acfs[np.newaxis, :]
+ elif ndim == 2:
+ pass
+ else:
+ raise ValueError("1D or 2D array required.")
+
+ # number of spectra, total length of full ACF
+ n, length = acfs.shape
+
+ # window width
+ ww = 2 * nw + 1
+
+ assert ww <= length, "Window cannot be wider than data."
+
+ # slice ACF data
+ data = acfs[:, length // 2 - nw : length // 2 + nw + 1].copy()
+ length_trim = data.shape[1]
+
+ # multiply by the window
+ data *= f_w(ww)
+
+ # pad with optional zeros along time axis
+ # one extra zero for symmetry - keep the ACF an even function
+ data = np.pad(data, ((0, 0), (npad + 1, npad)), "constant", constant_values=0.0)
+ assert data.shape == (n, length_trim + 2 * npad + 1)
+
+ # window width including zero padding
+ wwp = data.shape[1]
+
+ # frequencies, with the provided real-space step
+ frequency = np.fft.rfftfreq(wwp, d=d)
+
+ # FFT ACF to spectrum
+ # N.B.: For an ACF that is an even function, imaginary part is strictly zero.
+ # This is general, though.
+ data_fft = np.fft.rfft(data)
+ intensity = np.abs(data_fft)
+
+ # Make result consistent with input in 1D case.
+ if ndim == 1:
+ intensity = intensity[0, :]
+
+ # Normalize intensities to 1:
+ intensity = intensity / intensity.sum()
+
+ return frequency, intensity
+
+
+def get_acfs(source: list[np.ndarray]) -> np.ndarray:
+ """
+ Calculate averaged autocorrelation function for a number of timeseries.
+
+ The `source` yields individual timeseries and each of those is a
+ timeseries of vector quantity. This means that if you
+ want only a single autocorrelation function, you need to wrap the input
+ array in something iterable, like a list.
+
+ Parameters
+ ----------
+ source
+ Iterator over timeseries of dimension N by 3.
+
+ Returns
+ -------
+ ndarray
+ ACFs, as many as timeseries yielded by `source`.
+ """
+ acfs = []
+ for data in source:
+ n = len(data[:, 0])
+ norm = n - np.abs(np.arange(1 - n, n), dtype=float)
+ cfs = [
+ signal.correlate(data[:, d], data[:, d], mode="full", method="auto") / norm
+ for d in range(3)
+ ]
+ acfs.append(np.array(cfs).sum(axis=0))
+ return np.array(acfs).mean(axis=0)
+
+
+def get_spectra(
+ acfs: np.ndarray,
+ dt: float,
+ dt_window: float,
+ dt_pad: float = 0.0,
+ f_w: callable = np.hanning,
+) -> tuple[np.ndarray, np.ndarray]:
+ """
+ Calculate spectra from autocorrelation functions using FFT.
+
+ Processes multiple spectra at the same time, depending on the data in `acfs`.
+
+ Parameters
+ ----------
+ acfs
+ CFs numpy array.
+ dt
+ Time step, in femtoseconds.
+ dt_window
+ Total (double-sided) width of window, in femtoseconds.
+ dt_pad
+ Additional (double-sided) width of padding, in femtoseconds. Default is 0.0.
+ f_w
+ Function used to generate a (symmetric) window. Default is np.hanning.
+
+ Returns
+ -------
+ tuple
+ Frequency (nu) and intensity arrays.
+ """
+ c = 299792458.0 # m / s
+
+ # check the input
+ if dt_window <= 0.0:
+ raise ValueError("`Dt` must be positive.")
+ if dt_pad < 0.0:
+ raise ValueError("`Dt_pad` must not be negative.")
+ if dt * len(acfs) < dt_window:
+ msg = (
+ "The window ({:.0f} fs) must be narrower than the data "
+ "({:.0f} fs). Alas, it is not."
+ )
+ raise ValueError(msg.format(dt_window, dt * len(acfs)))
+
+ nw = int(dt_window / dt / 2.0)
+ npad = int(dt_pad / dt / 2.0)
+
+ frequency, intensity = _acfs_to_spectra(acfs, nw, npad=npad, d=1e-15 * dt, f_w=f_w)
+
+ # convert frequency from Hz to cm^-1
+ nu = frequency / (100.0 * c)
+
+ return nu, intensity
+
+
+def get_unique_atom_types(topology: mdt.Topology) -> list[str]:
+ """
+ Determine the unique atom types in a trajectory.
+
+ Parameters
+ ----------
+ topology
+ Topology object from mdtraj trajectory.
+
+ Returns
+ -------
+ list
+ List of unique atom type names.
+ """
+ return list({atom.name for atom in topology.atoms})
+
+
+def get_unique_elements(topology: mdt.Topology) -> list[str]:
+ """
+ Determine the unique elements in a trajectory.
+
+ Parameters
+ ----------
+ topology
+ Topology object from mdtraj trajectory.
+
+ Returns
+ -------
+ list
+ List of unique element symbols.
+ """
+ return list({atom.element.symbol for atom in topology.atoms})
+
+
+def compute_all_errors(
+ ref_fnc: dict[str, tuple[np.ndarray, np.ndarray]],
+ test_fnc: dict[str, tuple[np.ndarray, np.ndarray]],
+) -> dict[str, list]:
+ """
+ Compute MAEs relative to reference data.
+
+ Given two sets of functions returns the mean absolute error
+ of the test functions relative to the reference (first argument).
+
+ Parameters
+ ----------
+ ref_fnc
+ Reference functions dictionary.
+ test_fnc
+ Test functions dictionary.
+
+ Returns
+ -------
+ dict
+ Dictionary of errors with MAE values for each pair.
+ """
+ error = {}
+ for name, data in ref_fnc.items():
+ # Rescale array in case of different resolution
+ test_data = np.interp(data[0], test_fnc[name][0], test_fnc[name][1])
+ diff = data[1] - test_data
+ mae = np.sum(np.absolute(diff)) / (np.sum(data[1]) + np.sum(test_data))
+ error[name] = [data[0], diff, mae]
+ return error
+
+
+def print_errors(error: dict[str, list]) -> None:
+ """
+ Print the errors in a human readable way.
+
+ Parameters
+ ----------
+ error
+ Dictionary of errors with MAE values.
+ """
+ n = 22
+ print(n * "=")
+ print(f"{'Score Summary':{n}s}")
+ print(n * "=")
+ print("Label | Accuracy [%]")
+ print(n * "_")
+
+ all_err = []
+ for name, data in error.items():
+ err = (1 - data[2]) * 100
+ print(f"{name:7s} | {err:3.4}")
+ all_err.append(err)
+
+ # Mean of errors
+ name = "Mean"
+ err = np.mean(all_err)
+ print(f"{name:7s} | {err:3.4}")
+
+ print(n * "=")
+
+
+def plot_all_f_and_errors(
+ ref: dict[str, tuple[np.ndarray, np.ndarray]],
+ test: dict[str, tuple[np.ndarray, np.ndarray]],
+ error: dict[str, list],
+ observable: str,
+) -> None:
+ """
+ Loop over all functions and plot them, along with the error.
+
+ Parameters
+ ----------
+ ref
+ Reference functions dictionary.
+ test
+ Test functions dictionary.
+ error
+ Error dictionary.
+ observable
+ Observable name for plotting (e.g., "RDF", "VDOS").
+ """
+ for name, ref_data in ref.items():
+ plot_f_and_errors(ref_data, test[name], error[name], name, observable)
+
+
+def plot_f_and_errors(
+ ref: tuple[np.ndarray, np.ndarray],
+ test: tuple[np.ndarray, np.ndarray],
+ error: list,
+ title: str,
+ observable: str,
+) -> None:
+ """
+ Handle the plotting of the functions and their errors.
+
+ Parameters
+ ----------
+ ref
+ Reference function data.
+ test
+ Test function data.
+ error
+ Error data.
+ title
+ Title for the plot.
+ observable
+ Observable name for plotting (e.g., "RDF", "VDOS").
+ """
+ # Plot settings
+ cm2in = 1 / 2.54
+ fig = plt.figure(figsize=(8 * cm2in, 12 * cm2in), constrained_layout=True)
+ gs = fig.add_gridspec(ncols=1, nrows=2, height_ratios=[2.0, 1.0])
+
+ ax0 = fig.add_subplot(gs[0, 0])
+ ax1 = fig.add_subplot(gs[1, 0])
+
+ # Plot reference and test property
+ ax0.plot(ref[0], ref[1], color="black", label="Reference " + str(title), lw=2)
+ ax0.plot(
+ test[0],
+ test[1],
+ color="red",
+ dashes=(0.5, 1.5),
+ dash_capstyle="round",
+ label="Test " + str(title),
+ lw=2,
+ )
+
+ # Plot error
+ ax1.plot(error[0], error[1], color="black", lw=2)
+
+ # Formatting
+ ax0.set_ylabel(observable)
+ ax0.set_xticklabels([])
+ ax1.set_ylabel("Absolute Error")
+ if observable == "VDOS":
+ ax0.set_ylim(ymin=0)
+ ax0.set_xlim([0, 4500])
+ ax1.set_xlim([0, 4500])
+ ax1.set_xlabel(r"Frequency (cm$^{-1}$)")
+ if observable == "RDF":
+ ax1.set_xlabel(r"Distance ($\mathrm{\AA{}}$)")
+
+ ax0.set_title("Species: " + str(title))
+
+ plt.savefig(observable + "-" + str(title) + ".pdf")
+
+
+def plot_mae_errors(error: dict[str, list], fn_out: str = "accuracy-all.pdf") -> None:
+ """
+ Plot the summed absolute errors for each element.
+
+ Parameters
+ ----------
+ error
+ Dictionary of errors with MAE values.
+ fn_out
+ Output filename for the plot. Default is "accuracy-all.pdf".
+ """
+
+ def autolabel(rects: list, form: str = r"{:1.1f}") -> None:
+ """
+ Attach a text label in each bar in rects, displaying its value.
+
+ Parameters
+ ----------
+ rects
+ Bar rectangles from matplotlib.
+ form
+ Format string for label. Default is r"{:1.1f}".
+ """
+ for rect in rects:
+ width = rect.get_width()
+ plt.annotate(
+ form.format(width),
+ xy=(0.0, rect.get_y() + rect.get_height() / 2),
+ xytext=(3, 0), # 3 points vertical offset
+ textcoords="offset points",
+ ha="left",
+ va="center",
+ color="w",
+ fontsize=8,
+ fontweight="bold",
+ )
+
+ # Plot settings
+ cm2in = 1 / 2.54
+ cm = plt.cm.viridis(np.linspace(0, 1.0, 8))[::-1]
+ fig, ax = plt.subplots(
+ ncols=1, nrows=1, constrained_layout=True, figsize=(8 * cm2in, 6 * cm2in)
+ )
+
+ # height of the bars
+ height = 0.6
+ # Label and their locations
+ y = np.arange(len(error) + 1)
+ labels = list(error.keys())
+
+ # Convert errors to percent
+ errors = np.array([(1 - error[key][2]) * 100 for key in labels][::-1])
+
+ # Plot individual errors and mean
+ rects = ax.barh(y[1:], errors, height, color=cm[4])
+ autolabel(rects)
+ rects = ax.barh(y[0], errors.mean(), height, color=cm[6])
+ autolabel(rects)
+
+ # Formatting
+ ax.set_yticks(y)
+ ax.set_yticklabels(np.append(labels, "All")[::-1])
+ ax.set_xlim([0, 100])
+ ax.set_xlabel("Accuracy (%)")
+ ax.set_frame_on(False)
+ ax.grid(axis="x")
+
+ if fn_out is not None:
+ plt.savefig(fn_out)
+
+
+def run_vdos_test(
+ ref_trj: mdt.Trajectory,
+ ref_dt: float,
+ test_trj: mdt.Trajectory,
+ test_dt: float,
+ fn_out: str = "vdos-res.pkl",
+) -> None:
+ """
+ Perform the VDOS scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ ref_dt
+ Reference time step.
+ test_trj
+ Test trajectory.
+ test_dt
+ Test time step.
+ fn_out
+ Output filename for results. Default is "vdos-res.pkl".
+ """
+ # Compute all RDFs
+ ref_vdos = compute_all_vdos(ref_trj, ref_dt)
+ test_vdos = compute_all_vdos(test_trj, test_dt)
+
+ # Compute the errors
+ vdos_errors = compute_all_errors(ref_vdos, test_vdos)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_vdos, test_vdos, vdos_errors, observable="VDOS")
+ plot_mae_errors(vdos_errors, fn_out="vdos-all.pdf")
+
+ # Print the errors
+ print_errors(vdos_errors)
+
+ # Save results
+ results = {"ref_vdos": ref_vdos, "test_vdos": test_vdos, "vdos_errors": vdos_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def run_vdos_single(
+ ref_trj: mdt.Trajectory,
+ ref_dt: float,
+ fn_out: str = "vdos-res.pkl",
+) -> None:
+ """
+ Perform the VDOS scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ ref_dt
+ Reference time step.
+ fn_out
+ Output filename for results. Default is "vdos-res.pkl".
+ """
+ # Compute all RDFs
+ ref_vdos = compute_all_vdos(ref_trj, ref_dt)
+
+ for name, ref_data in ref_vdos.items():
+ # Plot settings
+ cm2in = 1 / 2.54
+ fig = plt.figure(figsize=(8 * cm2in, 6 * cm2in), constrained_layout=True)
+ gs = fig.add_gridspec(ncols=1, nrows=1)
+
+ ax0 = fig.add_subplot(gs[0, 0])
+
+ # Plot reference and test property
+ ax0.plot(ref_data[0], ref_data[1], color="black", lw=2)
+
+ # Formatting
+ ax0.set_ylabel("vdos")
+ ax0.set_xticklabels([])
+ ax0.set_ylim(ymin=0)
+ ax0.set_xlim([0, 4500])
+ ax0.set_title("Species: " + str(name))
+
+ plt.savefig("VDOS-single-" + str(name) + ".pdf")
+
+
+def compute_all_vdos(
+ trj: mdt.Trajectory,
+ dt: float = 1,
+ dt_window: float = 2000.0,
+ dt_pad: float = 2000.0,
+) -> dict[str, tuple[np.ndarray, np.ndarray]]:
+ """
+ Compute VDOS separately for all atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj
+ MDTraj trajectory object.
+ dt
+ Time step. Default is 1.
+ dt_window
+ Total window width. Default is 2000.0.
+ dt_pad
+ Padding width. Default is 2000.0.
+
+ Returns
+ -------
+ dict
+ Dictionary of VDOS data for each atom type.
+ """
+ top = trj.topology
+
+ vdos_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(top)
+
+ for t1 in atom_types:
+ # select indices of the atom type
+ idx_t1 = top.select("name " + t1)
+
+ # calculate velocity autocorrelation functions,
+ # averaged over atoms of this species
+ cfs = get_acfs(trj.xyz.transpose(1, 0, 2)[idx_t1])
+
+ # calculate the spectrum for this species and store it
+ nu, intensity = get_spectra(
+ cfs,
+ dt=dt,
+ dt_window=dt_window,
+ dt_pad=dt_pad,
+ )
+ vdos_all[t1] = nu, intensity
+
+ return vdos_all
+
+
+def parse_velocities_all(filename: str) -> list:
+ """
+ Read velocities from an extended XYZ with momenta using ASE.
+
+ Reads an extended XYZ with momenta using ASE and returns
+ per-frame velocities calculated as momenta / mass.
+
+ Parameters
+ ----------
+ filename
+ Path to the XYZ file.
+
+ Returns
+ -------
+ list
+ List of structures with velocities.
+ """
+ traj = read(filename, index=":") # read all frames
+ structures = []
+
+ for atoms in traj:
+ momenta = atoms.get_momenta() # (N, 3)
+ masses = atoms.get_masses()[:, None] # (N, 1) for broadcasting
+ velocities = momenta / masses # v = p / m
+
+ symbols = atoms.get_chemical_symbols()
+
+ frame = [
+ (sym, v[0], v[1], v[2]) for sym, v in zip(symbols, velocities, strict=False)
+ ]
+ structures.append(frame)
+
+ return structures
+
+
+def write_velocities_traj_all(structures: list, output_file: str) -> None:
+ """
+ Write velocities trajectory to file.
+
+ Parameters
+ ----------
+ structures
+ List of structures with velocities.
+ output_file
+ Path to output file.
+ """
+ with open(output_file, "w") as file:
+ for structure in structures:
+ file.write(f"{len(structure)}\n")
+ file.write('Properties=species:S:1:vel:R:3 pbc="T T T"\n')
+ for atom_name, vx, vy, vz in structure:
+ file.write(f"{atom_name:2s} {vx:12.7f} {vy:12.7f} {vz:12.7f}\n")
+
+
+def compute_all_rdfs(
+ trj: mdt.Trajectory,
+ n_bins: int = 150,
+ **kwargs,
+) -> dict[str, tuple[np.ndarray, np.ndarray]]:
+ """
+ Compute RDFs between all pairs of atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj
+ MDTraj trajectory object.
+ n_bins
+ Number of bins for RDF calculation. Default is 150.
+ **kwargs
+ Additional keyword arguments passed to mdt.compute_rdf.
+
+ Returns
+ -------
+ dict
+ Dictionary of RDF data for each atom type pair.
+ """
+ top = trj.topology
+
+ rdfs_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(trj.topology)
+
+ for i1, t1 in enumerate(atom_types):
+ # select indices of the first atom type
+ idx_t1 = top.select("name " + t1)
+
+ # unique atom type pairs only
+ for i2 in range(i1, len(atom_types)):
+ t2 = atom_types[i2]
+
+ # select indices of the second atom type
+ idx_t2 = top.select("name " + t2)
+
+ # prepare all pairs of indices
+ pairs = trj.topology.select_pairs(idx_t1, idx_t2)
+
+ # single atom with itself -> no RDF
+ if len(pairs) == 0:
+ continue
+
+ # OM: not sure this should be done here
+ min_dimension = trj[0].unitcell_lengths.min() / 2
+
+ r, g_r = mdt.compute_rdf(
+ trj, pairs, (0, min_dimension), n_bins=n_bins, **kwargs
+ )
+
+ rdfs_all[t1 + "-" + t2] = r, g_r
+
+ return rdfs_all
+
+
+def run_rdf_test(
+ ref_trj: mdt.Trajectory,
+ test_trj: mdt.Trajectory,
+ fn_out: str = "rdf-res.pkl",
+) -> None:
+ """
+ Perform the RDF scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ test_trj
+ Test trajectory.
+ fn_out
+ Output filename for results. Default is "rdf-res.pkl".
+ """
+ # Compute all RDFs
+ ref_rdf = compute_all_rdfs(ref_trj)
+ test_rdf = compute_all_rdfs(test_trj)
+
+ # Compute the errors
+ rdf_errors = compute_all_errors(ref_rdf, test_rdf)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_rdf, test_rdf, rdf_errors, observable="RDF")
+ plot_mae_errors(rdf_errors, fn_out="rdf-all.pdf")
+
+ # Print the errors
+ print_errors(rdf_errors)
+
+ # Save results
+ results = {"ref_rdf": ref_rdf, "test_rdf": test_rdf, "rdf_errors": rdf_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def load_with_cell(
+ filename_or_filenames: str | list[str],
+ start: int | None = None,
+ stop: int | None = None,
+ step: int | None = None,
+ **kwargs,
+) -> mdt.Trajectory:
+ """
+ Load trajectory and inject cell dimensions from topology PDB file if not present.
+
+ All arguments and keyword arguments are passed on to `mdtraj.load`. The `top`
+ keyword argument is used to load a PDB file and get cell information from it.
+
+ Parameters
+ ----------
+ filename_or_filenames
+ Filename or list of filenames to load.
+ start
+ Starting frame index. Default is None.
+ stop
+ Stopping frame index. Default is None.
+ step
+ Frame step. Default is None.
+ **kwargs
+ Additional keyword arguments passed to mdtraj.load.
+
+ Returns
+ -------
+ mdtraj.Trajectory
+ Loaded trajectory with cell information.
+ """
+ # load the "topology frame" to get cell dimensions
+ top = kwargs.get("top")
+ if top is not None and isinstance(top, str):
+ # load first frame from file as topology
+ frame_top = mdt.load_frame(top, 0)
+ unitcell_lengths = frame_top.unitcell_lengths
+ unitcell_angles = frame_top.unitcell_angles
+ if (unitcell_lengths is None) or (unitcell_angles is None):
+ raise ValueError("Frame providing topology is missing cell information.")
+ else:
+ raise ValueError("Provide a PDB with cell dimensions.")
+
+ # load the trajectory itself
+ trj = mdt.load(filename_or_filenames, **kwargs)
+ trj = trj[start:stop:step]
+
+ # inject the cell information
+ len_trj = len(trj)
+ trj.unitcell_lengths = unitcell_lengths.repeat(len_trj, axis=0)
+ trj.unitcell_angles = unitcell_angles.repeat(len_trj, axis=0)
+
+ return trj
+
+
+def error_score_percentage(mae: float) -> float:
+ """
+ Calculate error score as a percentage from mean absolute error.
+
+ Parameters
+ ----------
+ mae
+ Mean absolute error value.
+
+ Returns
+ -------
+ float
+ Error score as a percentage (0-100).
+ """
+ return (1 - mae) * 100
+
+
+############################
+### NEW FUNCTIONS FOR VACFS
+############################
+
+
+def compute_all_errors_vacf(ref_fnc, test_fnc):
+ """
+ Compute MAEs relative to reference data.
+
+ Given two sets of functions returns the mean absolute error
+ of the test functions relative to the reference (first argument).
+
+ Parameters
+ ----------
+ ref_fnc : dict
+ Reference function data.
+ test_fnc : dict
+ Test function data.
+
+ Returns
+ -------
+ dict
+ Dictionary containing error data for each function.
+ """
+ error = {}
+ for name, data in ref_fnc.items():
+ # Rescale array in case of different resolution
+ test_data = np.interp(data[0], test_fnc[name][0], test_fnc[name][1])
+ diff = data[1] - test_data
+ mae = np.sum(np.abs(diff)) / (
+ np.sum(np.abs(data[1])) + np.sum(np.abs(test_data))
+ )
+ error[name] = [data[0], diff, mae]
+ return error
+
+
+def run_vacfs_test(ref_trj, ref_dt, test_trj, test_dt, fn_out="vcaf-res.pkl"):
+ """
+ Perform the VCAF scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj : mdtraj.Trajectory
+ Reference trajectory.
+ ref_dt : float
+ Reference trajectory time step.
+ test_trj : mdtraj.Trajectory
+ Test trajectory.
+ test_dt : float
+ Test trajectory time step.
+ fn_out : str, default "vcaf-res.pkl"
+ Output filename for results.
+ """
+ # Compute all RDFs
+ ref_vacf = compute_all_vacfs(ref_trj, ref_dt)
+ test_vacf = compute_all_vacfs(test_trj, test_dt)
+
+ # Compute the errors
+ vacf_errors = compute_all_errors_vacf(ref_vacf, test_vacf)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_vacf, test_vacf, vacf_errors, observable="VACF")
+ plot_mae_errors(vacf_errors, fn_out="vacfs-all.pdf")
+
+ # Print the errors
+ print_errors(vacf_errors)
+
+ # Save results
+ results = {"ref_vacf": ref_vacf, "test_vacf": test_vacf, "vacf_errors": vacf_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def compute_all_vacfs(trj, dt=1):
+ """
+ Compute VDOS separately for all atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj : mdtraj.Trajectory
+ Trajectory data.
+ dt : float, default 1
+ Time step.
+
+ Returns
+ -------
+ dict
+ Dictionary containing VACF data for all atom types.
+ """
+ top = trj.topology
+
+ vacfs_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(top)
+
+ for t1 in atom_types:
+ # select indices of the atom type
+ idx_t1 = top.select("name " + t1)
+
+ # velocities assumed in Å/fs
+ # shape: (n_frames, n_atoms, 3)
+ vel = trj.xyz.transpose(1, 0, 2)[idx_t1]
+
+ # compute velocity autocorrelation
+ # expected shape: (n_lags,)
+ vacf = get_acfs(vel)
+
+ # time axis
+ t = np.arange(len(vacf)) * dt # fs
+
+ # center index
+ i0 = len(vacf) // 2
+
+ # keep only t >= 0
+ vacf = vacf[i0:]
+ t = t[: len(vacf)]
+
+ # normalize to sort out any units missmatch
+ vacf /= vacf[0]
+
+ vacfs_all[t1] = (t, vacf)
+
+ return vacfs_all
diff --git a/ml_peg/analysis/aqueous_solutions/bulk_water/analyse_bulk_water.py b/ml_peg/analysis/aqueous_solutions/bulk_water/analyse_bulk_water.py
new file mode 100644
index 000000000..73b24bacb
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/bulk_water/analyse_bulk_water.py
@@ -0,0 +1,800 @@
+"""Analysis of bulk water benchmark."""
+
+from __future__ import annotations
+
+from pathlib import Path
+import pickle
+
+from ase.io import read
+import mdtraj as mdt
+import numpy as np
+import pytest
+
+from ml_peg.analysis.aqueous_solutions.bulk_water import aml
+from ml_peg.analysis.aqueous_solutions.bulk_water.decorators import (
+ cell_to_bar,
+)
+from ml_peg.analysis.utils.decorators import (
+ build_table,
+)
+from ml_peg.analysis.utils.utils import load_metrics_config
+from ml_peg.app import APP_ROOT
+from ml_peg.calcs import CALCS_ROOT
+from ml_peg.calcs.utils.utils import download_s3_data
+from ml_peg.models.get_models import get_model_names
+from ml_peg.models.models import current_models
+
+MODELS = get_model_names(current_models)
+CALC_PATH = CALCS_ROOT / "aqueous_solutions" / "bulk_water" / "outputs"
+OUT_PATH = APP_ROOT / "data" / "aqueous_solutions" / "bulk_water"
+RDF_CURVE_PATH = OUT_PATH / "rdf_curves"
+VDOS_CURVE_PATH = OUT_PATH / "vdos_curves"
+VACF_CURVE_PATH = OUT_PATH / "vacf_curves"
+
+
+METRIC_LABELS = {
+ "rdf_score": "RDF Score",
+ "vdos_score": "VDOS Score",
+ "vacf_score": "VACF Score",
+}
+METRICS_CONFIG_PATH = Path(__file__).with_name("metrics.yml")
+DEFAULT_THRESHOLDS, DEFAULT_TOOLTIPS, DEFAULT_WEIGHTS = load_metrics_config(
+ METRICS_CONFIG_PATH
+)
+
+DATA_PATH = (
+ download_s3_data(
+ filename="bulk_water.zip",
+ key="inputs/aqueous_solutions/bulk_water/bulk_water.zip",
+ )
+ / "bulk_water"
+)
+REF_VEL_PATH = DATA_PATH / "pbe-d3-md-vel.xyz"
+
+
+def get_rdf_keys() -> list:
+ """
+ Return list of relevant RDF key names.
+
+ Returns
+ -------
+ list
+ List of all RDF keys.
+ """
+ rdf_keys = []
+ xyz_file = DATA_PATH / "init.xyz"
+ atoms = read(xyz_file)
+ all_species = set(atoms.get_chemical_symbols())
+ all_species = sorted(all_species)
+ for species1 in all_species:
+ for species2 in all_species:
+ pair = "-".join(sorted([species1, species2]))
+ if pair not in rdf_keys:
+ rdf_keys.append(pair)
+ return rdf_keys
+
+
+def get_elements() -> list:
+ """
+ Return list of relevant element names.
+
+ Returns
+ -------
+ list
+ List of all elements.
+ """
+ elements = set()
+ xyz_file = DATA_PATH / "init.xyz"
+ atoms = read(xyz_file)
+ for symbol in atoms.get_chemical_symbols():
+ elements.add(symbol)
+ return sorted(elements)
+
+
+@pytest.fixture
+def created_rdfs() -> dict[str, dict]:
+ """
+ Create RDFs for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of RDFs for all models.
+ """
+ rdfs = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/rdf_reference.pkl", "rb") as f_in:
+ rdfs["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if rdf curves directory exists, if not create it
+ if not RDF_CURVE_PATH.exists():
+ RDF_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if rdf curves directory exists for model, if not create it
+ if not (RDF_CURVE_PATH / model_name).exists():
+ (RDF_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ position_xyz = model_dir / "md-pos.xyz"
+ if not position_xyz.exists():
+ continue
+
+ test_trj = aml.load_with_cell(position_xyz, top=ref_topology)
+
+ rdfs[model_name] = aml.compute_all_rdfs(test_trj)
+
+ # Make sure keys are in alphabetical order
+ rdfs_keys = list(rdfs[model_name].keys())
+ for key in rdfs_keys:
+ split_key = key.split("-")
+ split_key.sort()
+ altered_key = "-".join(split_key)
+ if altered_key != key:
+ rdfs[model_name][altered_key] = rdfs[model_name].pop(key)
+
+ # Write rdf curves to file for app use
+ with open(RDF_CURVE_PATH / model_name / "rdf_curves.pkl", "wb") as f_out:
+ pickle.dump(rdfs[model_name], f_out)
+
+ return rdfs
+
+
+def plot_rdfs(model: str, element_pair: str, rdf: dict, error: bool = False) -> None:
+ """
+ Plot RDF paths and save all structure files.
+
+ Parameters
+ ----------
+ model
+ Name of MLIP.
+ element_pair
+ Element pair for RDF.
+ rdf
+ RDF data.
+ error
+ Whether to plot error or raw RDF.
+ """
+
+ def plot_rdf() -> dict[str, tuple[list[float], list[float]]]:
+ """
+ Plot a RDF and save the structure file.
+
+ Returns
+ -------
+ dict[str, tuple[list[float], list[float]]]
+ Dictionary of tuples of image/energy for each model.
+ """
+ results = {}
+ results[model] = [
+ rdf[0].tolist(),
+ rdf[1].tolist(),
+ ]
+
+ return results
+
+ plot_rdf()
+
+
+@pytest.fixture
+def rdf_scores(created_rdfs: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average RDF score for all models.
+
+ Parameters
+ ----------
+ created_rdfs
+ Created RDFs for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average RDF scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_rdfs[model_name] is None:
+ continue
+ rdf_errors = aml.compute_all_errors(
+ created_rdfs["ref"], created_rdfs[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ rdf_scores = [
+ aml.error_score_percentage(error[2]) for error in rdf_errors.values()
+ ]
+
+ results[model_name] = rdf_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in rdf_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+def mean_rdf_score(rdf_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean RDF score for all models.
+
+ Parameters
+ ----------
+ rdf_scores
+ Average RDF scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean RDF scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in rdf_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+# -------- VDOS
+
+
+@pytest.fixture
+def created_vdos() -> dict[str, dict]:
+ """
+ Create VDOS for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of VDOS for all models.
+ """
+ vdos = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/vdos_reference.pkl", "rb") as f_in:
+ vdos["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if vdos curves directory exists, if not create it
+ if not VDOS_CURVE_PATH.exists():
+ VDOS_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if vdos curves directory exists for model, if not create it
+ if not (VDOS_CURVE_PATH / model_name).exists():
+ (VDOS_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ vel_xyz = model_dir / "md-velc.xyz"
+ if not vel_xyz.exists():
+ continue
+
+ test_vel = mdt.load(vel_xyz, top=ref_topology, stride=1)
+ test_top = mdt.load_pdb(ref_topology)
+
+ test_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(test_vel), axis=0
+ )
+ test_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(test_vel), axis=0
+ )
+
+ ref_dt = 1
+
+ vdos[model_name] = aml.compute_all_vdos(test_vel, ref_dt)
+
+ # Write rdf curves to file for app use
+ with open(VDOS_CURVE_PATH / model_name / "vdos_curves.pkl", "wb") as f_out:
+ pickle.dump(vdos[model_name], f_out)
+
+ return vdos
+
+
+@pytest.fixture
+def vdos_scores(created_vdos: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average VDOS score for all models.
+
+ Parameters
+ ----------
+ created_vdos
+ Created VDOS for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average VDOS scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_vdos[model_name] is None:
+ continue
+ vdos_errors = aml.compute_all_errors(
+ created_vdos["ref"], created_vdos[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ vdos_scores = [
+ aml.error_score_percentage(error[2]) for error in vdos_errors.values()
+ ]
+ results[model_name] = vdos_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in vdos_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+def mean_vdos_score(vdos_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean VDOS score for all models.
+
+ Parameters
+ ----------
+ vdos_scores
+ Average VDOS scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean VDOS scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in vdos_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "rdf_score_bar.json",
+ x_label="X Coord",
+ y_label="RDF Score",
+)
+def build_rdf_interactive_data(
+ rdf_scores: dict[str, list], created_rdfs: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for RDF bar plot.
+
+ Parameters
+ ----------
+ rdf_scores
+ Average RDF scores for all models.
+ created_rdfs
+ Created RDFs for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for RDF bar plot.
+ """
+ # Get all unique RDF pairs from the reference data
+ ref_pairs = list(created_rdfs["ref"].keys()) if created_rdfs["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if rdf_scores.get(model_name) is None or created_rdfs.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_rdfs["ref"]
+ model_rdf_data = created_rdfs[model_name]
+
+ # Get scores for each RDF pair
+ rdf_errors = aml.compute_all_errors(ref_data, model_rdf_data)
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["rdf_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in rdf_errors:
+ error_data = rdf_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_rdf_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "g(r)",
+ "xlabel": "Distance (Å)", # error array
+ "xlim": [0, 0.6],
+ },
+ }
+ )
+ model_data["metrics"]["rdf_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["rdf_score"] = "RDF Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "vdos_score_bar.json",
+ x_label="Element",
+ y_label="VDOS Score",
+)
+def build_vdos_interactive_data(
+ vdos_scores: dict[str, list], created_vdos: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for VDOS bar plot.
+
+ Parameters
+ ----------
+ vdos_scores
+ Average VDOS scores for all models.
+ created_vdos
+ Created VDOS for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for VDOS bar plot.
+ """
+ # Get all unique VDOS pairs from the reference data
+ ref_pairs = list(created_vdos["ref"].keys()) if created_vdos["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if vdos_scores.get(model_name) is None or created_vdos.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_vdos["ref"]
+ model_vdos_data = created_vdos[model_name]
+
+ # Get scores for each VDOS pair
+ vdos_errors = aml.compute_all_errors(ref_data, model_vdos_data)
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["vdos_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in vdos_errors:
+ error_data = vdos_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_vdos_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "Intensity (a.u)",
+ "xlabel": "Frequency (cm⁻¹)", # error array
+ "xlim": [0, 4000],
+ },
+ }
+ )
+ model_data["metrics"]["vdos_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["vdos_score"] = "VDOS Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+# ----------------------+----------------------+---------------------- #
+# ----------------------+-------- VACF --------+---------------------- #
+# ----------------------+----------------------+---------------------- #
+
+
+@pytest.fixture
+def created_vacf() -> dict[str, dict]:
+ """
+ Create VACF for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of VACF for all models.
+ """
+ vacf = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/vacf_reference.pkl", "rb") as f_in:
+ vacf["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if vacf curves directory exists, if not create it
+ if not VACF_CURVE_PATH.exists():
+ VACF_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if vacf curves directory exists for model, if not create it
+ if not (VACF_CURVE_PATH / model_name).exists():
+ (VACF_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ vel_xyz = model_dir / "md-velc.xyz"
+ if not vel_xyz.exists():
+ continue
+
+ test_vel = mdt.load(vel_xyz, top=ref_topology, stride=1)
+ # Truncate to same length as reference
+ test_top = mdt.load_pdb(ref_topology)
+
+ test_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(test_vel), axis=0
+ )
+ test_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(test_vel), axis=0
+ )
+
+ ref_dt = 1
+
+ # Check if length of trajectory matches reference
+ ref_length = len(list(vacf["ref"].values())[0][0])
+ test_length = len(test_vel)
+ min_length = min(test_length, ref_length)
+
+ if vacf["ref"] is not None:
+ if test_length != ref_length:
+ # Truncate both to shortest length - and recalculate reference if needed
+
+ test_vel = test_vel[test_length - min_length :]
+ if len(test_vel) != ref_length:
+ ref_vel = mdt.load(REF_VEL_PATH, top=ref_topology, stride=1)
+ ref_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(ref_vel), axis=0
+ )
+ ref_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(ref_vel), axis=0
+ )
+ ref_vel_trunc = ref_vel[ref_length - min_length :]
+ vacf_ref_trunc = aml.compute_all_vacfs(ref_vel_trunc, ref_dt)
+ # Write updated reference vacf curves to file for app use
+
+ else:
+ vacf_ref_trunc = vacf["ref"]
+
+ vacf[f"ref_{model_name}"] = vacf_ref_trunc
+ vacf[model_name] = aml.compute_all_vacfs(test_vel, ref_dt)
+
+ # Write rdf curves to file for app use
+ with open(VACF_CURVE_PATH / model_name / "vacf_curves.pkl", "wb") as f_out:
+ pickle.dump(vacf[model_name], f_out)
+
+ return vacf
+
+
+@pytest.fixture
+def vacf_scores(created_vacf: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average VACF score for all models.
+
+ Parameters
+ ----------
+ created_vacf
+ Created VACF for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average VACF scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_vacf[model_name] is None:
+ continue
+ vacf_errors = aml.compute_all_errors_vacf(
+ created_vacf[f"ref_{model_name}"], created_vacf[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ vacf_scores = [
+ aml.error_score_percentage(error[2]) for error in vacf_errors.values()
+ ]
+ results[model_name] = vacf_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in vacf_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "vacf_score_bar.json",
+ x_label="Element",
+ y_label="VACF Score",
+)
+def build_vacf_interactive_data(
+ vacf_scores: dict[str, list], created_vacf: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for VACF bar plot.
+
+ Parameters
+ ----------
+ vacf_scores
+ Average VACF scores for all models.
+ created_vacf
+ Created VACF for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for VACF bar plot.
+ """
+ # Get all unique VACF pairs from the reference data
+ ref_pairs = list(created_vacf["ref"].keys()) if created_vacf["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if vacf_scores.get(model_name) is None or created_vacf.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_vacf[f"ref_{model_name}"]
+ model_vacf_data = created_vacf[model_name]
+
+ # Get scores for each VACF pair
+ vacf_errors = aml.compute_all_errors_vacf(ref_data, created_vacf[model_name])
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["vacf_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in vacf_errors:
+ error_data = vacf_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_vacf_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "VACF",
+ "xlabel": "Time [fs]", # error array
+ },
+ }
+ )
+ model_data["metrics"]["vacf_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["vacf_score"] = "VACF Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+@pytest.fixture
+def mean_vacf_score(vacf_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean VACF score for all models.
+
+ Parameters
+ ----------
+ vacf_scores
+ Average VACF scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean VACF scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in vacf_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+@pytest.fixture
+@build_table(
+ filename=OUT_PATH / "bulk_water_metrics_table.json",
+ metric_tooltips=DEFAULT_TOOLTIPS,
+ thresholds=DEFAULT_THRESHOLDS,
+)
+def metrics(
+ mean_rdf_score: dict[str, float],
+ mean_vdos_score: dict[str, float],
+ mean_vacf_score: dict[str, float],
+) -> dict[str, dict]:
+ """
+ Get all metrics.
+
+ Parameters
+ ----------
+ mean_rdf_score
+ Mean RDF score for all models.
+ mean_vdos_score
+ Mean VDOS score for all models.
+ mean_vacf_score
+ Mean VACF score for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Metric names and values for all models.
+ """
+ return {
+ "rdf_score": mean_rdf_score,
+ "vdos_score": mean_vdos_score,
+ "vacf_score": mean_vacf_score,
+ }
+
+
+def test_bulk_water(
+ metrics: dict[str, dict],
+ build_rdf_interactive_data: dict,
+ build_vdos_interactive_data: dict,
+ build_vacf_interactive_data: dict,
+) -> None:
+ """
+ Run bulk water tests.
+
+ Parameters
+ ----------
+ metrics
+ All bulk water metrics.
+ build_rdf_interactive_data
+ Interactive data for RDF bar plot.
+ build_vdos_interactive_data
+ Interactive data for VDOS bar plot.
+ build_vacf_interactive_data
+ Interactive data for VACF bar plot.
+ """
+ return
+
+
+"""@plot_parity(
+ filename=OUT_PATH / "figure_rdf_score.json",
+ title="RDF",
+ x_label="Predicted RDF score",
+ y_label="Reference RDF score",
+ hoverdata={'RDF-pair': get_rdf_keys()},
+)"""
diff --git a/ml_peg/analysis/aqueous_solutions/bulk_water/decorators.py b/ml_peg/analysis/aqueous_solutions/bulk_water/decorators.py
new file mode 100644
index 000000000..5efaeee8a
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/bulk_water/decorators.py
@@ -0,0 +1,255 @@
+"""Fixtures for MLIP results analysis for bulk_water."""
+
+from __future__ import annotations
+
+from collections.abc import Callable
+import functools
+import json
+from json import dump
+from pathlib import Path
+from typing import Any
+
+import plotly.graph_objects as go
+
+
+def cell_to_bar(
+ *,
+ filename: str | Path,
+ x_label: str | None = None,
+ y_label: str | None = None,
+ title_template: str = "{model} - {metric}",
+) -> Callable:
+ """
+ Pre-generate bar plots for each table cell (model-metric pair).
+
+ Use this for benchmarks where each table CELL generates its own bar plot
+ (e.g., clicking MACE's ω_max shows a bar for that specific model-metric
+ pair). For benchmarks where clicking a COLUMN shows all models on one bar
+ (like S24 or OC157), use @plot_parity instead.
+
+ This decorator generates complete Plotly figures during analysis instead of
+ saving raw points for the app to process on-the-fly.
+
+ Parameters
+ ----------
+ filename
+ Path where JSON data with pre-made figures will be saved.
+ x_label
+ Label for x-axis (typically "Score"). Default is None.
+ y_label
+ Label for y-axis (typically "Names of Variables"). Default is None.
+ title_template
+ Template for plot titles with {model} and {metric} placeholders.
+ Default is "{model} - {metric}".
+
+ Returns
+ -------
+ Callable
+ Decorator that wraps analysis functions to pre-generate bar figures.
+ """
+
+ def decorator(func: Callable) -> Callable:
+ """
+ Wrap the decorated callable to pre-generate bar figures.
+
+ Parameters
+ ----------
+ func
+ Analysis function returning the dataset consumed by the Dash app.
+
+ Returns
+ -------
+ Callable
+ Wrapped function that runs ``func`` and emits Plotly figures.
+ """
+
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ """
+ Execute func and generate bar plots for each model-metric pair.
+
+ Parameters
+ ----------
+ *args
+ Positional arguments forwarded to ``func``.
+ **kwargs
+ Keyword arguments forwarded to ``func``.
+
+ Returns
+ -------
+ dict
+ The dataset produced by ``func`` (with ``figures`` entries).
+ """
+ data_bundle = func(*args, **kwargs)
+
+ # Extract metadata
+ metric_labels = data_bundle.get("metrics", {})
+ models_data = data_bundle.get("models", {})
+
+ # Create figures for each model-metric pair
+ for model_name, model_data in models_data.items():
+ model_data["figures"] = {}
+ metrics_data = model_data.get("metrics", {})
+
+ for metric_key, metric_info in metrics_data.items():
+ # Extract ref and pred values
+
+ labels = [minfo["label"] for minfo in metric_info]
+ values = [minfo["value"] for minfo in metric_info]
+
+ # Build hovertemplate
+ hovertemplate = (
+ "Score: %{x}
Ref: %{y}
"
+ "Label: %{customdata[0]}
"
+ )
+ # Create figure
+ fig = go.Figure()
+ fig.add_trace(
+ go.Bar(
+ x=labels,
+ y=values,
+ customdata=[
+ [lab, minfo["data"]]
+ for lab, minfo in zip(labels, metric_info, strict=False)
+ ],
+ hovertemplate=hovertemplate,
+ showlegend=False,
+ )
+ )
+ # Set ylimits as 0 to 105
+ fig.update_yaxes(range=[0, 105])
+
+ # Update layout
+ metric_label = metric_labels.get(metric_key, metric_key)
+ title = title_template.format(model=model_name, metric=metric_label)
+ fig.update_layout(
+ title={"text": title},
+ xaxis={"title": {"text": x_label}},
+ yaxis={"title": {"text": y_label}},
+ )
+
+ # Store figure as JSON-serializable dict
+ models_data[model_name]["figures"][metric_key] = json.loads(
+ fig.to_json()
+ )
+
+ # Save to file
+ Path(filename).parent.mkdir(parents=True, exist_ok=True)
+ with open(filename, "w", encoding="utf8") as f:
+ dump(data_bundle, f)
+
+ return data_bundle
+
+ return wrapper
+
+ return decorator
+
+
+def plot_hist(
+ title: str | None = None,
+ x_label: str | None = None,
+ y_label: str | None = None,
+ hoverdata: dict | None = None,
+ filename: str = "histogram.json",
+ nbins: int = 50,
+ bin_range: tuple[float, float] | None = None,
+) -> Callable:
+ """
+ Plot histogram of MLIP results against reference data.
+
+ Parameters
+ ----------
+ title
+ Graph title.
+ x_label
+ Label for x-axis. Default is `None`.
+ y_label
+ Label for y-axis. Default is `None`.
+ hoverdata
+ Hover data dictionary. Default is `{}`.
+ filename
+ Filename to save plot as JSON. Default is "parity.json".
+ nbins
+ Number of bins for histogram. Default is 50.
+ bin_range
+ Tuple specifying the range of bins (min, max). Default is `None`
+ (automatically determined).
+
+ Returns
+ -------
+ Callable
+ Decorator to wrap function.
+ """
+
+ def plot_hist_decorator(func: Callable) -> Callable:
+ """
+ Decorate function to plot histogram.
+
+ Parameters
+ ----------
+ func
+ Function being wrapped.
+
+ Returns
+ -------
+ Callable
+ Wrapped function.
+ """
+
+ @functools.wraps(func)
+ def plot_hist_wrapper(*args, **kwargs) -> dict[str, Any]:
+ """
+ Wrap function to plot histogram.
+
+ Parameters
+ ----------
+ *args
+ Arguments to pass to the function being wrapped.
+ **kwargs
+ Key word arguments to pass to the function being wrapped.
+
+ Returns
+ -------
+ dict
+ Results dictionary.
+ """
+ results = func(*args, **kwargs)
+
+ hovertemplate = "Bin: %{x}
" + "Density: %{y}
"
+
+ customdata = []
+ if hoverdata:
+ for i, key in enumerate(hoverdata):
+ hovertemplate += f"{key}: %{{customdata[{i}]}}
"
+ customdata = list(zip(*hoverdata.values(), strict=True))
+
+ fig = go.Figure()
+ for mlip, value in results.items():
+ fig.add_trace(
+ go.Scatter(
+ x=value["bins"],
+ y=value["hist"],
+ name=mlip,
+ mode="lines",
+ customdata=customdata,
+ hovertemplate=hovertemplate,
+ )
+ )
+
+ fig.update_layout(
+ title={"text": title},
+ xaxis={"title": {"text": x_label}},
+ yaxis={"title": {"text": y_label}},
+ )
+
+ fig.update_traces()
+
+ # Write to file
+ Path(filename).parent.mkdir(parents=True, exist_ok=True)
+ fig.write_json(filename)
+
+ return results
+
+ return plot_hist_wrapper
+
+ return plot_hist_decorator
diff --git a/ml_peg/analysis/aqueous_solutions/bulk_water/metrics.yml b/ml_peg/analysis/aqueous_solutions/bulk_water/metrics.yml
new file mode 100644
index 000000000..88ca21e34
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/bulk_water/metrics.yml
@@ -0,0 +1,19 @@
+metrics:
+ rdf_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: RDF d score
+ level_of_theory: PBE-D3
+ vdos_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: vdos_score
+ level_of_theory: PBE-D3
+ vacf_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: vacf_score
+ level_of_theory: PBE-D3
diff --git a/ml_peg/analysis/aqueous_solutions/ice/aml.py b/ml_peg/analysis/aqueous_solutions/ice/aml.py
new file mode 100644
index 000000000..17fdad573
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/ice/aml.py
@@ -0,0 +1,918 @@
+"""Analysis module for ice. Upon usage cite Schran et al, PNAS, 2021."""
+
+from __future__ import annotations
+
+import pickle
+
+from ase.io import read
+import matplotlib.pyplot as plt
+import mdtraj as mdt
+import numpy as np
+from scipy import signal
+
+
+def _acfs_to_spectra(
+ acfs: np.ndarray,
+ nw: int,
+ npad: int = 0,
+ d: float = 1.0,
+ f_w: callable = np.hanning,
+) -> tuple[np.ndarray, np.ndarray]:
+ """
+ Calculate spectra from autocorrelation functions using FFT.
+
+ Optionally processes multiple spectra at the same time. In that case,
+ `acfs` is a 2D array of shape number of ACFs by length of ACFs. This is a
+ low-level function, use `get_spectra` for a more convenient interface.
+
+ Parameters
+ ----------
+ acfs
+ Array, 1D or 2D, symmetric full ACFs.
+ nw
+ One-sided number of points of ACF window.
+ npad
+ One-sided number of additional padding zeros. Default is 0.
+ d
+ Real-space step. Default is 1.0.
+ f_w
+ Function to evaluate the double-sided symmetric window. Default is np.hanning.
+
+ Returns
+ -------
+ tuple
+ Frequency and intensity arrays.
+ """
+ # Make sure we're processing a 2D array.
+ ndim = len(acfs.shape)
+ if ndim == 1:
+ acfs = acfs[np.newaxis, :]
+ elif ndim == 2:
+ pass
+ else:
+ raise ValueError("1D or 2D array required.")
+
+ # number of spectra, total length of full ACF
+ n, length = acfs.shape
+
+ # window width
+ ww = 2 * nw + 1
+
+ assert ww <= length, "Window cannot be wider than data."
+
+ # slice ACF data
+ data = acfs[:, length // 2 - nw : length // 2 + nw + 1].copy()
+ length_trim = data.shape[1]
+
+ # multiply by the window
+ data *= f_w(ww)
+
+ # pad with optional zeros along time axis
+ # one extra zero for symmetry - keep the ACF an even function
+ data = np.pad(data, ((0, 0), (npad + 1, npad)), "constant", constant_values=0.0)
+ assert data.shape == (n, length_trim + 2 * npad + 1)
+
+ # window width including zero padding
+ wwp = data.shape[1]
+
+ # frequencies, with the provided real-space step
+ frequency = np.fft.rfftfreq(wwp, d=d)
+
+ # FFT ACF to spectrum
+ # N.B.: For an ACF that is an even function, imaginary part is strictly zero.
+ # This is general, though.
+ data_fft = np.fft.rfft(data)
+ intensity = np.abs(data_fft)
+
+ # Make result consistent with input in 1D case.
+ if ndim == 1:
+ intensity = intensity[0, :]
+
+ # Normalize intensities to 1:
+ intensity = intensity / intensity.sum()
+
+ return frequency, intensity
+
+
+def get_acfs(source: list[np.ndarray]) -> np.ndarray:
+ """
+ Calculate averaged autocorrelation function for a number of timeseries.
+
+ The `source` yields individual timeseries and each of those is a
+ timeseries of vector quantity. This means that if you
+ want only a single autocorrelation function, you need to wrap the input
+ array in something iterable, like a list.
+
+ Parameters
+ ----------
+ source
+ Iterator over timeseries of dimension N by 3.
+
+ Returns
+ -------
+ ndarray
+ ACFs, as many as timeseries yielded by `source`.
+ """
+ acfs = []
+ for data in source:
+ n = len(data[:, 0])
+ norm = n - np.abs(np.arange(1 - n, n), dtype=float)
+ cfs = [
+ signal.correlate(data[:, d], data[:, d], mode="full", method="auto") / norm
+ for d in range(3)
+ ]
+ acfs.append(np.array(cfs).sum(axis=0))
+ return np.array(acfs).mean(axis=0)
+
+
+def get_spectra(
+ acfs: np.ndarray,
+ dt: float,
+ dt_window: float,
+ dt_pad: float = 0.0,
+ f_w: callable = np.hanning,
+) -> tuple[np.ndarray, np.ndarray]:
+ """
+ Calculate spectra from autocorrelation functions using FFT.
+
+ Processes multiple spectra at the same time, depending on the data in `acfs`.
+
+ Parameters
+ ----------
+ acfs
+ CFs numpy array.
+ dt
+ Time step, in femtoseconds.
+ dt_window
+ Total (double-sided) width of window, in femtoseconds.
+ dt_pad
+ Additional (double-sided) width of padding, in femtoseconds. Default is 0.0.
+ f_w
+ Function used to generate a (symmetric) window. Default is np.hanning.
+
+ Returns
+ -------
+ tuple
+ Frequency (nu) and intensity arrays.
+ """
+ c = 299792458.0 # m / s
+
+ # check the input
+ if dt_window <= 0.0:
+ raise ValueError("`Dt` must be positive.")
+ if dt_pad < 0.0:
+ raise ValueError("`Dt_pad` must not be negative.")
+ if dt * len(acfs) < dt_window:
+ msg = (
+ "The window ({:.0f} fs) must be narrower than the data "
+ "({:.0f} fs). Alas, it is not."
+ )
+ raise ValueError(msg.format(dt_window, dt * len(acfs)))
+
+ nw = int(dt_window / dt / 2.0)
+ npad = int(dt_pad / dt / 2.0)
+
+ frequency, intensity = _acfs_to_spectra(acfs, nw, npad=npad, d=1e-15 * dt, f_w=f_w)
+
+ # convert frequency from Hz to cm^-1
+ nu = frequency / (100.0 * c)
+
+ return nu, intensity
+
+
+def get_unique_atom_types(topology: mdt.Topology) -> list[str]:
+ """
+ Determine the unique atom types in a trajectory.
+
+ Parameters
+ ----------
+ topology
+ Topology object from mdtraj trajectory.
+
+ Returns
+ -------
+ list
+ List of unique atom type names.
+ """
+ return list({atom.name for atom in topology.atoms})
+
+
+def get_unique_elements(topology: mdt.Topology) -> list[str]:
+ """
+ Determine the unique elements in a trajectory.
+
+ Parameters
+ ----------
+ topology
+ Topology object from mdtraj trajectory.
+
+ Returns
+ -------
+ list
+ List of unique element symbols.
+ """
+ return list({atom.element.symbol for atom in topology.atoms})
+
+
+def compute_all_errors(
+ ref_fnc: dict[str, tuple[np.ndarray, np.ndarray]],
+ test_fnc: dict[str, tuple[np.ndarray, np.ndarray]],
+) -> dict[str, list]:
+ """
+ Compute MAEs relative to reference data.
+
+ Given two sets of functions returns the mean absolute error
+ of the test functions relative to the reference (first argument).
+
+ Parameters
+ ----------
+ ref_fnc
+ Reference functions dictionary.
+ test_fnc
+ Test functions dictionary.
+
+ Returns
+ -------
+ dict
+ Dictionary of errors with MAE values for each pair.
+ """
+ error = {}
+ for name, data in ref_fnc.items():
+ # Rescale array in case of different resolution
+ test_data = np.interp(data[0], test_fnc[name][0], test_fnc[name][1])
+ diff = data[1] - test_data
+ mae = np.sum(np.absolute(diff)) / (np.sum(data[1]) + np.sum(test_data))
+ error[name] = [data[0], diff, mae]
+ return error
+
+
+def print_errors(error: dict[str, list]) -> None:
+ """
+ Print the errors in a human readable way.
+
+ Parameters
+ ----------
+ error
+ Dictionary of errors with MAE values.
+ """
+ n = 22
+ print(n * "=")
+ print(f"{'Score Summary':{n}s}")
+ print(n * "=")
+ print("Label | Accuracy [%]")
+ print(n * "_")
+
+ all_err = []
+ for name, data in error.items():
+ err = (1 - data[2]) * 100
+ print(f"{name:7s} | {err:3.4}")
+ all_err.append(err)
+
+ # Mean of errors
+ name = "Mean"
+ err = np.mean(all_err)
+ print(f"{name:7s} | {err:3.4}")
+
+ print(n * "=")
+
+
+def plot_all_f_and_errors(
+ ref: dict[str, tuple[np.ndarray, np.ndarray]],
+ test: dict[str, tuple[np.ndarray, np.ndarray]],
+ error: dict[str, list],
+ observable: str,
+) -> None:
+ """
+ Loop over all functions and plot them, along with the error.
+
+ Parameters
+ ----------
+ ref
+ Reference functions dictionary.
+ test
+ Test functions dictionary.
+ error
+ Error dictionary.
+ observable
+ Observable name for plotting (e.g., "RDF", "VDOS").
+ """
+ for name, ref_data in ref.items():
+ plot_f_and_errors(ref_data, test[name], error[name], name, observable)
+
+
+def plot_f_and_errors(
+ ref: tuple[np.ndarray, np.ndarray],
+ test: tuple[np.ndarray, np.ndarray],
+ error: list,
+ title: str,
+ observable: str,
+) -> None:
+ """
+ Handle the plotting of the functions and their errors.
+
+ Parameters
+ ----------
+ ref
+ Reference function data.
+ test
+ Test function data.
+ error
+ Error data.
+ title
+ Title for the plot.
+ observable
+ Observable name for plotting (e.g., "RDF", "VDOS").
+ """
+ # Plot settings
+ cm2in = 1 / 2.54
+ fig = plt.figure(figsize=(8 * cm2in, 12 * cm2in), constrained_layout=True)
+ gs = fig.add_gridspec(ncols=1, nrows=2, height_ratios=[2.0, 1.0])
+
+ ax0 = fig.add_subplot(gs[0, 0])
+ ax1 = fig.add_subplot(gs[1, 0])
+
+ # Plot reference and test property
+ ax0.plot(ref[0], ref[1], color="black", label="Reference " + str(title), lw=2)
+ ax0.plot(
+ test[0],
+ test[1],
+ color="red",
+ dashes=(0.5, 1.5),
+ dash_capstyle="round",
+ label="Test " + str(title),
+ lw=2,
+ )
+
+ # Plot error
+ ax1.plot(error[0], error[1], color="black", lw=2)
+
+ # Formatting
+ ax0.set_ylabel(observable)
+ ax0.set_xticklabels([])
+ ax1.set_ylabel("Absolute Error")
+ if observable == "VDOS":
+ ax0.set_ylim(ymin=0)
+ ax0.set_xlim([0, 4500])
+ ax1.set_xlim([0, 4500])
+ ax1.set_xlabel(r"Frequency (cm$^{-1}$)")
+ if observable == "RDF":
+ ax1.set_xlabel(r"Distance ($\mathrm{\AA{}}$)")
+
+ ax0.set_title("Species: " + str(title))
+
+ plt.savefig(observable + "-" + str(title) + ".pdf")
+
+
+def plot_mae_errors(error: dict[str, list], fn_out: str = "accuracy-all.pdf") -> None:
+ """
+ Plot the summed absolute errors for each element.
+
+ Parameters
+ ----------
+ error
+ Dictionary of errors with MAE values.
+ fn_out
+ Output filename for the plot. Default is "accuracy-all.pdf".
+ """
+
+ def autolabel(rects: list, form: str = r"{:1.1f}") -> None:
+ """
+ Attach a text label in each bar in rects, displaying its value.
+
+ Parameters
+ ----------
+ rects
+ Bar rectangles from matplotlib.
+ form
+ Format string for label. Default is r"{:1.1f}".
+ """
+ for rect in rects:
+ width = rect.get_width()
+ plt.annotate(
+ form.format(width),
+ xy=(0.0, rect.get_y() + rect.get_height() / 2),
+ xytext=(3, 0), # 3 points vertical offset
+ textcoords="offset points",
+ ha="left",
+ va="center",
+ color="w",
+ fontsize=8,
+ fontweight="bold",
+ )
+
+ # Plot settings
+ cm2in = 1 / 2.54
+ cm = plt.cm.viridis(np.linspace(0, 1.0, 8))[::-1]
+ fig, ax = plt.subplots(
+ ncols=1, nrows=1, constrained_layout=True, figsize=(8 * cm2in, 6 * cm2in)
+ )
+
+ # height of the bars
+ height = 0.6
+ # Label and their locations
+ y = np.arange(len(error) + 1)
+ labels = list(error.keys())
+
+ # Convert errors to percent
+ errors = np.array([(1 - error[key][2]) * 100 for key in labels][::-1])
+
+ # Plot individual errors and mean
+ rects = ax.barh(y[1:], errors, height, color=cm[4])
+ autolabel(rects)
+ rects = ax.barh(y[0], errors.mean(), height, color=cm[6])
+ autolabel(rects)
+
+ # Formatting
+ ax.set_yticks(y)
+ ax.set_yticklabels(np.append(labels, "All")[::-1])
+ ax.set_xlim([0, 100])
+ ax.set_xlabel("Accuracy (%)")
+ ax.set_frame_on(False)
+ ax.grid(axis="x")
+
+ if fn_out is not None:
+ plt.savefig(fn_out)
+
+
+def run_vdos_test(
+ ref_trj: mdt.Trajectory,
+ ref_dt: float,
+ test_trj: mdt.Trajectory,
+ test_dt: float,
+ fn_out: str = "vdos-res.pkl",
+) -> None:
+ """
+ Perform the VDOS scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ ref_dt
+ Reference time step.
+ test_trj
+ Test trajectory.
+ test_dt
+ Test time step.
+ fn_out
+ Output filename for results. Default is "vdos-res.pkl".
+ """
+ # Compute all RDFs
+ ref_vdos = compute_all_vdos(ref_trj, ref_dt)
+ test_vdos = compute_all_vdos(test_trj, test_dt)
+
+ # Compute the errors
+ vdos_errors = compute_all_errors(ref_vdos, test_vdos)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_vdos, test_vdos, vdos_errors, observable="VDOS")
+ plot_mae_errors(vdos_errors, fn_out="vdos-all.pdf")
+
+ # Print the errors
+ print_errors(vdos_errors)
+
+ # Save results
+ results = {"ref_vdos": ref_vdos, "test_vdos": test_vdos, "vdos_errors": vdos_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def run_vdos_single(
+ ref_trj: mdt.Trajectory,
+ ref_dt: float,
+ fn_out: str = "vdos-res.pkl",
+) -> None:
+ """
+ Perform the VDOS scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ ref_dt
+ Reference time step.
+ fn_out
+ Output filename for results. Default is "vdos-res.pkl".
+ """
+ # Compute all RDFs
+ ref_vdos = compute_all_vdos(ref_trj, ref_dt)
+
+ for name, ref_data in ref_vdos.items():
+ # Plot settings
+ cm2in = 1 / 2.54
+ fig = plt.figure(figsize=(8 * cm2in, 6 * cm2in), constrained_layout=True)
+ gs = fig.add_gridspec(ncols=1, nrows=1)
+
+ ax0 = fig.add_subplot(gs[0, 0])
+
+ # Plot reference and test property
+ ax0.plot(ref_data[0], ref_data[1], color="black", lw=2)
+
+ # Formatting
+ ax0.set_ylabel("vdos")
+ ax0.set_xticklabels([])
+ ax0.set_ylim(ymin=0)
+ ax0.set_xlim([0, 4500])
+ ax0.set_title("Species: " + str(name))
+
+ plt.savefig("VDOS-single-" + str(name) + ".pdf")
+
+
+def compute_all_vdos(
+ trj: mdt.Trajectory,
+ dt: float = 1,
+ dt_window: float = 2000.0,
+ dt_pad: float = 2000.0,
+) -> dict[str, tuple[np.ndarray, np.ndarray]]:
+ """
+ Compute VDOS separately for all atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj
+ MDTraj trajectory object.
+ dt
+ Time step. Default is 1.
+ dt_window
+ Total window width. Default is 2000.0.
+ dt_pad
+ Padding width. Default is 2000.0.
+
+ Returns
+ -------
+ dict
+ Dictionary of VDOS data for each atom type.
+ """
+ top = trj.topology
+
+ vdos_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(top)
+
+ for t1 in atom_types:
+ # select indices of the atom type
+ idx_t1 = top.select("name " + t1)
+
+ # calculate velocity autocorrelation functions,
+ # averaged over atoms of this species
+ cfs = get_acfs(trj.xyz.transpose(1, 0, 2)[idx_t1])
+
+ # calculate the spectrum for this species and store it
+ nu, intensity = get_spectra(
+ cfs,
+ dt=dt,
+ dt_window=dt_window,
+ dt_pad=dt_pad,
+ )
+ vdos_all[t1] = nu, intensity
+
+ return vdos_all
+
+
+def parse_velocities_all(filename: str) -> list:
+ """
+ Read velocities from an extended XYZ with momenta using ASE.
+
+ Reads an extended XYZ with momenta using ASE and returns
+ per-frame velocities calculated as momenta / mass.
+
+ Parameters
+ ----------
+ filename
+ Path to the XYZ file.
+
+ Returns
+ -------
+ list
+ List of structures with velocities.
+ """
+ traj = read(filename, index=":") # read all frames
+ structures = []
+
+ for atoms in traj:
+ momenta = atoms.get_momenta() # (N, 3)
+ masses = atoms.get_masses()[:, None] # (N, 1) for broadcasting
+ velocities = momenta / masses # v = p / m
+
+ symbols = atoms.get_chemical_symbols()
+
+ frame = [
+ (sym, v[0], v[1], v[2]) for sym, v in zip(symbols, velocities, strict=False)
+ ]
+ structures.append(frame)
+
+ return structures
+
+
+def write_velocities_traj_all(structures: list, output_file: str) -> None:
+ """
+ Write velocities trajectory to file.
+
+ Parameters
+ ----------
+ structures
+ List of structures with velocities.
+ output_file
+ Path to output file.
+ """
+ with open(output_file, "w") as file:
+ for structure in structures:
+ file.write(f"{len(structure)}\n")
+ file.write('Properties=species:S:1:vel:R:3 pbc="T T T"\n')
+ for atom_name, vx, vy, vz in structure:
+ file.write(f"{atom_name:2s} {vx:12.7f} {vy:12.7f} {vz:12.7f}\n")
+
+
+def compute_all_rdfs(
+ trj: mdt.Trajectory,
+ n_bins: int = 150,
+ **kwargs,
+) -> dict[str, tuple[np.ndarray, np.ndarray]]:
+ """
+ Compute RDFs between all pairs of atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj
+ MDTraj trajectory object.
+ n_bins
+ Number of bins for RDF calculation. Default is 150.
+ **kwargs
+ Additional keyword arguments passed to mdt.compute_rdf.
+
+ Returns
+ -------
+ dict
+ Dictionary of RDF data for each atom type pair.
+ """
+ top = trj.topology
+
+ rdfs_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(trj.topology)
+
+ for i1, t1 in enumerate(atom_types):
+ # select indices of the first atom type
+ idx_t1 = top.select("name " + t1)
+
+ # unique atom type pairs only
+ for i2 in range(i1, len(atom_types)):
+ t2 = atom_types[i2]
+
+ # select indices of the second atom type
+ idx_t2 = top.select("name " + t2)
+
+ # prepare all pairs of indices
+ pairs = trj.topology.select_pairs(idx_t1, idx_t2)
+
+ # single atom with itself -> no RDF
+ if len(pairs) == 0:
+ continue
+
+ # OM: not sure this should be done here
+ min_dimension = trj[0].unitcell_lengths.min() / 2
+
+ r, g_r = mdt.compute_rdf(
+ trj, pairs, (0, min_dimension), n_bins=n_bins, **kwargs
+ )
+
+ rdfs_all[t1 + "-" + t2] = r, g_r
+
+ return rdfs_all
+
+
+def run_rdf_test(
+ ref_trj: mdt.Trajectory,
+ test_trj: mdt.Trajectory,
+ fn_out: str = "rdf-res.pkl",
+) -> None:
+ """
+ Perform the RDF scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ test_trj
+ Test trajectory.
+ fn_out
+ Output filename for results. Default is "rdf-res.pkl".
+ """
+ # Compute all RDFs
+ ref_rdf = compute_all_rdfs(ref_trj)
+ test_rdf = compute_all_rdfs(test_trj)
+
+ # Compute the errors
+ rdf_errors = compute_all_errors(ref_rdf, test_rdf)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_rdf, test_rdf, rdf_errors, observable="RDF")
+ plot_mae_errors(rdf_errors, fn_out="rdf-all.pdf")
+
+ # Print the errors
+ print_errors(rdf_errors)
+
+ # Save results
+ results = {"ref_rdf": ref_rdf, "test_rdf": test_rdf, "rdf_errors": rdf_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def load_with_cell(
+ filename_or_filenames: str | list[str],
+ start: int | None = None,
+ stop: int | None = None,
+ step: int | None = None,
+ **kwargs,
+) -> mdt.Trajectory:
+ """
+ Load trajectory and inject cell dimensions from topology PDB file if not present.
+
+ All arguments and keyword arguments are passed on to `mdtraj.load`. The `top`
+ keyword argument is used to load a PDB file and get cell information from it.
+
+ Parameters
+ ----------
+ filename_or_filenames
+ Filename or list of filenames to load.
+ start
+ Starting frame index. Default is None.
+ stop
+ Stopping frame index. Default is None.
+ step
+ Frame step. Default is None.
+ **kwargs
+ Additional keyword arguments passed to mdtraj.load.
+
+ Returns
+ -------
+ mdtraj.Trajectory
+ Loaded trajectory with cell information.
+ """
+ # load the "topology frame" to get cell dimensions
+ top = kwargs.get("top")
+ if top is not None and isinstance(top, str):
+ # load first frame from file as topology
+ frame_top = mdt.load_frame(top, 0)
+ unitcell_lengths = frame_top.unitcell_lengths
+ unitcell_angles = frame_top.unitcell_angles
+ if (unitcell_lengths is None) or (unitcell_angles is None):
+ raise ValueError("Frame providing topology is missing cell information.")
+ else:
+ raise ValueError("Provide a PDB with cell dimensions.")
+
+ # load the trajectory itself
+ trj = mdt.load(filename_or_filenames, **kwargs)
+ trj = trj[start:stop:step]
+
+ # inject the cell information
+ len_trj = len(trj)
+ trj.unitcell_lengths = unitcell_lengths.repeat(len_trj, axis=0)
+ trj.unitcell_angles = unitcell_angles.repeat(len_trj, axis=0)
+
+ return trj
+
+
+def error_score_percentage(mae: float) -> float:
+ """
+ Calculate error score as a percentage from mean absolute error.
+
+ Parameters
+ ----------
+ mae
+ Mean absolute error value.
+
+ Returns
+ -------
+ float
+ Error score as a percentage (0-100).
+ """
+ return (1 - mae) * 100
+
+
+############################
+### NEW FUNCTIONS FOR VACFS
+############################
+
+
+def compute_all_errors_vacf(ref_fnc, test_fnc):
+ """
+ Compute MAEs relative to reference data.
+
+ Given two sets of functions returns the mean absolute error
+ of the test functions relative to the reference (first argument).
+
+ Parameters
+ ----------
+ ref_fnc : dict
+ Reference function data.
+ test_fnc : dict
+ Test function data.
+
+ Returns
+ -------
+ dict
+ Dictionary containing error data for each function.
+ """
+ error = {}
+ for name, data in ref_fnc.items():
+ # Rescale array in case of different resolution
+ test_data = np.interp(data[0], test_fnc[name][0], test_fnc[name][1])
+ diff = data[1] - test_data
+ mae = np.sum(np.abs(diff)) / (
+ np.sum(np.abs(data[1])) + np.sum(np.abs(test_data))
+ )
+ error[name] = [data[0], diff, mae]
+ return error
+
+
+def run_vacfs_test(ref_trj, ref_dt, test_trj, test_dt, fn_out="vcaf-res.pkl"):
+ """
+ Perform the VCAF scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj : mdtraj.Trajectory
+ Reference trajectory.
+ ref_dt : float
+ Reference trajectory time step.
+ test_trj : mdtraj.Trajectory
+ Test trajectory.
+ test_dt : float
+ Test trajectory time step.
+ fn_out : str, default "vcaf-res.pkl"
+ Output filename for results.
+ """
+ # Compute all RDFs
+ ref_vacf = compute_all_vacfs(ref_trj, ref_dt)
+ test_vacf = compute_all_vacfs(test_trj, test_dt)
+
+ # Compute the errors
+ vacf_errors = compute_all_errors_vacf(ref_vacf, test_vacf)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_vacf, test_vacf, vacf_errors, observable="VACF")
+ plot_mae_errors(vacf_errors, fn_out="vacfs-all.pdf")
+
+ # Print the errors
+ print_errors(vacf_errors)
+
+ # Save results
+ results = {"ref_vacf": ref_vacf, "test_vacf": test_vacf, "vacf_errors": vacf_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def compute_all_vacfs(trj, dt=1):
+ """
+ Compute VDOS separately for all atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj : mdtraj.Trajectory
+ Trajectory data.
+ dt : float, default 1
+ Time step.
+
+ Returns
+ -------
+ dict
+ Dictionary containing VACF data for all atom types.
+ """
+ top = trj.topology
+
+ vacfs_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(top)
+
+ for t1 in atom_types:
+ # select indices of the atom type
+ idx_t1 = top.select("name " + t1)
+
+ # velocities assumed in Å/fs
+ # shape: (n_frames, n_atoms, 3)
+ vel = trj.xyz.transpose(1, 0, 2)[idx_t1]
+
+ # compute velocity autocorrelation
+ # expected shape: (n_lags,)
+ vacf = get_acfs(vel)
+
+ # time axis
+ t = np.arange(len(vacf)) * dt # fs
+
+ # center index
+ i0 = len(vacf) // 2
+
+ # keep only t >= 0
+ vacf = vacf[i0:]
+ t = t[: len(vacf)]
+
+ # normalize to sort out any units missmatch
+ vacf /= vacf[0]
+
+ vacfs_all[t1] = (t, vacf)
+
+ return vacfs_all
diff --git a/ml_peg/analysis/aqueous_solutions/ice/analyse_ice.py b/ml_peg/analysis/aqueous_solutions/ice/analyse_ice.py
new file mode 100644
index 000000000..ad21bbe23
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/ice/analyse_ice.py
@@ -0,0 +1,800 @@
+"""Analysis of ice benchmark."""
+
+from __future__ import annotations
+
+from pathlib import Path
+import pickle
+
+from ase.io import read
+import mdtraj as mdt
+import numpy as np
+import pytest
+
+from ml_peg.analysis.aqueous_solutions.ice import aml
+from ml_peg.analysis.aqueous_solutions.ice.decorators import (
+ cell_to_bar,
+)
+from ml_peg.analysis.utils.decorators import (
+ build_table,
+)
+from ml_peg.analysis.utils.utils import load_metrics_config
+from ml_peg.app import APP_ROOT
+from ml_peg.calcs import CALCS_ROOT
+from ml_peg.calcs.utils.utils import download_s3_data
+from ml_peg.models.get_models import get_model_names
+from ml_peg.models.models import current_models
+
+MODELS = get_model_names(current_models)
+CALC_PATH = CALCS_ROOT / "aqueous_solutions" / "ice" / "outputs"
+OUT_PATH = APP_ROOT / "data" / "aqueous_solutions" / "ice"
+RDF_CURVE_PATH = OUT_PATH / "rdf_curves"
+VDOS_CURVE_PATH = OUT_PATH / "vdos_curves"
+VACF_CURVE_PATH = OUT_PATH / "vacf_curves"
+
+
+METRIC_LABELS = {
+ "rdf_score": "RDF Score",
+ "vdos_score": "VDOS Score",
+ "vacf_score": "VACF Score",
+}
+METRICS_CONFIG_PATH = Path(__file__).with_name("metrics.yml")
+DEFAULT_THRESHOLDS, DEFAULT_TOOLTIPS, DEFAULT_WEIGHTS = load_metrics_config(
+ METRICS_CONFIG_PATH
+)
+
+DATA_PATH = (
+ download_s3_data(
+ filename="ice.zip",
+ key="inputs/aqueous_solutions/ice/ice.zip",
+ )
+ / "ice"
+)
+REF_VEL_PATH = DATA_PATH / "pbe-d3-md-vel.xyz"
+
+
+def get_rdf_keys() -> list:
+ """
+ Return list of relevant RDF key names.
+
+ Returns
+ -------
+ list
+ List of all RDF keys.
+ """
+ rdf_keys = []
+ xyz_file = DATA_PATH / "init.xyz"
+ atoms = read(xyz_file)
+ all_species = set(atoms.get_chemical_symbols())
+ all_species = sorted(all_species)
+ for species1 in all_species:
+ for species2 in all_species:
+ pair = "-".join(sorted([species1, species2]))
+ if pair not in rdf_keys:
+ rdf_keys.append(pair)
+ return rdf_keys
+
+
+def get_elements() -> list:
+ """
+ Return list of relevant element names.
+
+ Returns
+ -------
+ list
+ List of all elements.
+ """
+ elements = set()
+ xyz_file = DATA_PATH / "init.xyz"
+ atoms = read(xyz_file)
+ for symbol in atoms.get_chemical_symbols():
+ elements.add(symbol)
+ return sorted(elements)
+
+
+@pytest.fixture
+def created_rdfs() -> dict[str, dict]:
+ """
+ Create RDFs for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of RDFs for all models.
+ """
+ rdfs = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/rdf_reference.pkl", "rb") as f_in:
+ rdfs["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if rdf curves directory exists, if not create it
+ if not RDF_CURVE_PATH.exists():
+ RDF_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if rdf curves directory exists for model, if not create it
+ if not (RDF_CURVE_PATH / model_name).exists():
+ (RDF_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ position_xyz = model_dir / "md-pos.xyz"
+ if not position_xyz.exists():
+ continue
+
+ test_trj = aml.load_with_cell(position_xyz, top=ref_topology)
+
+ rdfs[model_name] = aml.compute_all_rdfs(test_trj)
+
+ # Make sure keys are in alphabetical order
+ rdfs_keys = list(rdfs[model_name].keys())
+ for key in rdfs_keys:
+ split_key = key.split("-")
+ split_key.sort()
+ altered_key = "-".join(split_key)
+ if altered_key != key:
+ rdfs[model_name][altered_key] = rdfs[model_name].pop(key)
+
+ # Write rdf curves to file for app use
+ with open(RDF_CURVE_PATH / model_name / "rdf_curves.pkl", "wb") as f_out:
+ pickle.dump(rdfs[model_name], f_out)
+
+ return rdfs
+
+
+def plot_rdfs(model: str, element_pair: str, rdf: dict, error: bool = False) -> None:
+ """
+ Plot RDF paths and save all structure files.
+
+ Parameters
+ ----------
+ model
+ Name of MLIP.
+ element_pair
+ Element pair for RDF.
+ rdf
+ RDF data.
+ error
+ Whether to plot error or raw RDF.
+ """
+
+ def plot_rdf() -> dict[str, tuple[list[float], list[float]]]:
+ """
+ Plot a RDF and save the structure file.
+
+ Returns
+ -------
+ dict[str, tuple[list[float], list[float]]]
+ Dictionary of tuples of image/energy for each model.
+ """
+ results = {}
+ results[model] = [
+ rdf[0].tolist(),
+ rdf[1].tolist(),
+ ]
+
+ return results
+
+ plot_rdf()
+
+
+@pytest.fixture
+def rdf_scores(created_rdfs: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average RDF score for all models.
+
+ Parameters
+ ----------
+ created_rdfs
+ Created RDFs for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average RDF scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_rdfs[model_name] is None:
+ continue
+ rdf_errors = aml.compute_all_errors(
+ created_rdfs["ref"], created_rdfs[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ rdf_scores = [
+ aml.error_score_percentage(error[2]) for error in rdf_errors.values()
+ ]
+
+ results[model_name] = rdf_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in rdf_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+def mean_rdf_score(rdf_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean RDF score for all models.
+
+ Parameters
+ ----------
+ rdf_scores
+ Average RDF scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean RDF scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in rdf_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+# -------- VDOS
+
+
+@pytest.fixture
+def created_vdos() -> dict[str, dict]:
+ """
+ Create VDOS for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of VDOS for all models.
+ """
+ vdos = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/vdos_reference.pkl", "rb") as f_in:
+ vdos["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if vdos curves directory exists, if not create it
+ if not VDOS_CURVE_PATH.exists():
+ VDOS_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if vdos curves directory exists for model, if not create it
+ if not (VDOS_CURVE_PATH / model_name).exists():
+ (VDOS_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ vel_xyz = model_dir / "md-velc.xyz"
+ if not vel_xyz.exists():
+ continue
+
+ test_vel = mdt.load(vel_xyz, top=ref_topology, stride=1)
+ test_top = mdt.load_pdb(ref_topology)
+
+ test_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(test_vel), axis=0
+ )
+ test_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(test_vel), axis=0
+ )
+
+ ref_dt = 1
+
+ vdos[model_name] = aml.compute_all_vdos(test_vel, ref_dt)
+
+ # Write rdf curves to file for app use
+ with open(VDOS_CURVE_PATH / model_name / "vdos_curves.pkl", "wb") as f_out:
+ pickle.dump(vdos[model_name], f_out)
+
+ return vdos
+
+
+@pytest.fixture
+def vdos_scores(created_vdos: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average VDOS score for all models.
+
+ Parameters
+ ----------
+ created_vdos
+ Created VDOS for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average VDOS scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_vdos[model_name] is None:
+ continue
+ vdos_errors = aml.compute_all_errors(
+ created_vdos["ref"], created_vdos[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ vdos_scores = [
+ aml.error_score_percentage(error[2]) for error in vdos_errors.values()
+ ]
+ results[model_name] = vdos_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in vdos_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+def mean_vdos_score(vdos_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean VDOS score for all models.
+
+ Parameters
+ ----------
+ vdos_scores
+ Average VDOS scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean VDOS scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in vdos_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "rdf_score_bar.json",
+ x_label="X Coord",
+ y_label="RDF Score",
+)
+def build_rdf_interactive_data(
+ rdf_scores: dict[str, list], created_rdfs: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for RDF bar plot.
+
+ Parameters
+ ----------
+ rdf_scores
+ Average RDF scores for all models.
+ created_rdfs
+ Created RDFs for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for RDF bar plot.
+ """
+ # Get all unique RDF pairs from the reference data
+ ref_pairs = list(created_rdfs["ref"].keys()) if created_rdfs["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if rdf_scores.get(model_name) is None or created_rdfs.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_rdfs["ref"]
+ model_rdf_data = created_rdfs[model_name]
+
+ # Get scores for each RDF pair
+ rdf_errors = aml.compute_all_errors(ref_data, model_rdf_data)
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["rdf_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in rdf_errors:
+ error_data = rdf_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_rdf_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "g(r)",
+ "xlabel": "Distance (Å)", # error array
+ "xlim": [0, 0.6],
+ },
+ }
+ )
+ model_data["metrics"]["rdf_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["rdf_score"] = "RDF Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "vdos_score_bar.json",
+ x_label="Element",
+ y_label="VDOS Score",
+)
+def build_vdos_interactive_data(
+ vdos_scores: dict[str, list], created_vdos: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for VDOS bar plot.
+
+ Parameters
+ ----------
+ vdos_scores
+ Average VDOS scores for all models.
+ created_vdos
+ Created VDOS for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for VDOS bar plot.
+ """
+ # Get all unique VDOS pairs from the reference data
+ ref_pairs = list(created_vdos["ref"].keys()) if created_vdos["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if vdos_scores.get(model_name) is None or created_vdos.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_vdos["ref"]
+ model_vdos_data = created_vdos[model_name]
+
+ # Get scores for each VDOS pair
+ vdos_errors = aml.compute_all_errors(ref_data, model_vdos_data)
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["vdos_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in vdos_errors:
+ error_data = vdos_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_vdos_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "Intensity (a.u)",
+ "xlabel": "Frequency (cm⁻¹)", # error array
+ "xlim": [0, 4000],
+ },
+ }
+ )
+ model_data["metrics"]["vdos_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["vdos_score"] = "VDOS Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+# ----------------------+----------------------+---------------------- #
+# ----------------------+-------- VACF --------+---------------------- #
+# ----------------------+----------------------+---------------------- #
+
+
+@pytest.fixture
+def created_vacf() -> dict[str, dict]:
+ """
+ Create VACF for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of VACF for all models.
+ """
+ vacf = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/vacf_reference.pkl", "rb") as f_in:
+ vacf["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if vacf curves directory exists, if not create it
+ if not VACF_CURVE_PATH.exists():
+ VACF_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if vacf curves directory exists for model, if not create it
+ if not (VACF_CURVE_PATH / model_name).exists():
+ (VACF_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ vel_xyz = model_dir / "md-velc.xyz"
+ if not vel_xyz.exists():
+ continue
+
+ test_vel = mdt.load(vel_xyz, top=ref_topology, stride=1)
+ # Truncate to same length as reference
+ test_top = mdt.load_pdb(ref_topology)
+
+ test_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(test_vel), axis=0
+ )
+ test_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(test_vel), axis=0
+ )
+
+ ref_dt = 1
+
+ # Check if length of trajectory matches reference
+ ref_length = len(list(vacf["ref"].values())[0][0])
+ test_length = len(test_vel)
+ min_length = min(test_length, ref_length)
+
+ if vacf["ref"] is not None:
+ if test_length != ref_length:
+ # Truncate both to shortest length - and recalculate reference if needed
+
+ test_vel = test_vel[test_length - min_length :]
+ if len(test_vel) != ref_length:
+ ref_vel = mdt.load(REF_VEL_PATH, top=ref_topology, stride=1)
+ ref_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(ref_vel), axis=0
+ )
+ ref_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(ref_vel), axis=0
+ )
+ ref_vel_trunc = ref_vel[ref_length - min_length :]
+ vacf_ref_trunc = aml.compute_all_vacfs(ref_vel_trunc, ref_dt)
+ # Write updated reference vacf curves to file for app use
+
+ else:
+ vacf_ref_trunc = vacf["ref"]
+
+ vacf[f"ref_{model_name}"] = vacf_ref_trunc
+ vacf[model_name] = aml.compute_all_vacfs(test_vel, ref_dt)
+
+ # Write rdf curves to file for app use
+ with open(VACF_CURVE_PATH / model_name / "vacf_curves.pkl", "wb") as f_out:
+ pickle.dump(vacf[model_name], f_out)
+
+ return vacf
+
+
+@pytest.fixture
+def vacf_scores(created_vacf: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average VACF score for all models.
+
+ Parameters
+ ----------
+ created_vacf
+ Created VACF for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average VACF scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_vacf[model_name] is None:
+ continue
+ vacf_errors = aml.compute_all_errors_vacf(
+ created_vacf[f"ref_{model_name}"], created_vacf[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ vacf_scores = [
+ aml.error_score_percentage(error[2]) for error in vacf_errors.values()
+ ]
+ results[model_name] = vacf_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in vacf_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "vacf_score_bar.json",
+ x_label="Element",
+ y_label="VACF Score",
+)
+def build_vacf_interactive_data(
+ vacf_scores: dict[str, list], created_vacf: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for VACF bar plot.
+
+ Parameters
+ ----------
+ vacf_scores
+ Average VACF scores for all models.
+ created_vacf
+ Created VACF for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for VACF bar plot.
+ """
+ # Get all unique VACF pairs from the reference data
+ ref_pairs = list(created_vacf["ref"].keys()) if created_vacf["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if vacf_scores.get(model_name) is None or created_vacf.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_vacf[f"ref_{model_name}"]
+ model_vacf_data = created_vacf[model_name]
+
+ # Get scores for each VACF pair
+ vacf_errors = aml.compute_all_errors_vacf(ref_data, created_vacf[model_name])
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["vacf_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in vacf_errors:
+ error_data = vacf_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_vacf_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "VACF",
+ "xlabel": "Time [fs]", # error array
+ },
+ }
+ )
+ model_data["metrics"]["vacf_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["vacf_score"] = "VACF Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+@pytest.fixture
+def mean_vacf_score(vacf_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean VACF score for all models.
+
+ Parameters
+ ----------
+ vacf_scores
+ Average VACF scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean VACF scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in vacf_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+@pytest.fixture
+@build_table(
+ filename=OUT_PATH / "ice_metrics_table.json",
+ metric_tooltips=DEFAULT_TOOLTIPS,
+ thresholds=DEFAULT_THRESHOLDS,
+)
+def metrics(
+ mean_rdf_score: dict[str, float],
+ mean_vdos_score: dict[str, float],
+ mean_vacf_score: dict[str, float],
+) -> dict[str, dict]:
+ """
+ Get all metrics.
+
+ Parameters
+ ----------
+ mean_rdf_score
+ Mean RDF score for all models.
+ mean_vdos_score
+ Mean VDOS score for all models.
+ mean_vacf_score
+ Mean VACF score for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Metric names and values for all models.
+ """
+ return {
+ "rdf_score": mean_rdf_score,
+ "vdos_score": mean_vdos_score,
+ "vacf_score": mean_vacf_score,
+ }
+
+
+def test_ice(
+ metrics: dict[str, dict],
+ build_rdf_interactive_data: dict,
+ build_vdos_interactive_data: dict,
+ build_vacf_interactive_data: dict,
+) -> None:
+ """
+ Run ice tests.
+
+ Parameters
+ ----------
+ metrics
+ All ice metrics.
+ build_rdf_interactive_data
+ Interactive data for RDF bar plot.
+ build_vdos_interactive_data
+ Interactive data for VDOS bar plot.
+ build_vacf_interactive_data
+ Interactive data for VACF bar plot.
+ """
+ return
+
+
+"""@plot_parity(
+ filename=OUT_PATH / "figure_rdf_score.json",
+ title="RDF",
+ x_label="Predicted RDF score",
+ y_label="Reference RDF score",
+ hoverdata={'RDF-pair': get_rdf_keys()},
+)"""
diff --git a/ml_peg/analysis/aqueous_solutions/ice/decorators.py b/ml_peg/analysis/aqueous_solutions/ice/decorators.py
new file mode 100644
index 000000000..cf422f358
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/ice/decorators.py
@@ -0,0 +1,255 @@
+"""Fixtures for MLIP results analysis for ice."""
+
+from __future__ import annotations
+
+from collections.abc import Callable
+import functools
+import json
+from json import dump
+from pathlib import Path
+from typing import Any
+
+import plotly.graph_objects as go
+
+
+def cell_to_bar(
+ *,
+ filename: str | Path,
+ x_label: str | None = None,
+ y_label: str | None = None,
+ title_template: str = "{model} - {metric}",
+) -> Callable:
+ """
+ Pre-generate bar plots for each table cell (model-metric pair).
+
+ Use this for benchmarks where each table CELL generates its own bar plot
+ (e.g., clicking MACE's ω_max shows a bar for that specific model-metric
+ pair). For benchmarks where clicking a COLUMN shows all models on one bar
+ (like S24 or OC157), use @plot_parity instead.
+
+ This decorator generates complete Plotly figures during analysis instead of
+ saving raw points for the app to process on-the-fly.
+
+ Parameters
+ ----------
+ filename
+ Path where JSON data with pre-made figures will be saved.
+ x_label
+ Label for x-axis (typically "Score"). Default is None.
+ y_label
+ Label for y-axis (typically "Names of Variables"). Default is None.
+ title_template
+ Template for plot titles with {model} and {metric} placeholders.
+ Default is "{model} - {metric}".
+
+ Returns
+ -------
+ Callable
+ Decorator that wraps analysis functions to pre-generate bar figures.
+ """
+
+ def decorator(func: Callable) -> Callable:
+ """
+ Wrap the decorated callable to pre-generate bar figures.
+
+ Parameters
+ ----------
+ func
+ Analysis function returning the dataset consumed by the Dash app.
+
+ Returns
+ -------
+ Callable
+ Wrapped function that runs ``func`` and emits Plotly figures.
+ """
+
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ """
+ Execute func and generate bar plots for each model-metric pair.
+
+ Parameters
+ ----------
+ *args
+ Positional arguments forwarded to ``func``.
+ **kwargs
+ Keyword arguments forwarded to ``func``.
+
+ Returns
+ -------
+ dict
+ The dataset produced by ``func`` (with ``figures`` entries).
+ """
+ data_bundle = func(*args, **kwargs)
+
+ # Extract metadata
+ metric_labels = data_bundle.get("metrics", {})
+ models_data = data_bundle.get("models", {})
+
+ # Create figures for each model-metric pair
+ for model_name, model_data in models_data.items():
+ model_data["figures"] = {}
+ metrics_data = model_data.get("metrics", {})
+
+ for metric_key, metric_info in metrics_data.items():
+ # Extract ref and pred values
+
+ labels = [minfo["label"] for minfo in metric_info]
+ values = [minfo["value"] for minfo in metric_info]
+
+ # Build hovertemplate
+ hovertemplate = (
+ "Score: %{x}
Ref: %{y}
"
+ "Label: %{customdata[0]}
"
+ )
+ # Create figure
+ fig = go.Figure()
+ fig.add_trace(
+ go.Bar(
+ x=labels,
+ y=values,
+ customdata=[
+ [lab, minfo["data"]]
+ for lab, minfo in zip(labels, metric_info, strict=False)
+ ],
+ hovertemplate=hovertemplate,
+ showlegend=False,
+ )
+ )
+ # Set ylimits as 0 to 105
+ fig.update_yaxes(range=[0, 105])
+
+ # Update layout
+ metric_label = metric_labels.get(metric_key, metric_key)
+ title = title_template.format(model=model_name, metric=metric_label)
+ fig.update_layout(
+ title={"text": title},
+ xaxis={"title": {"text": x_label}},
+ yaxis={"title": {"text": y_label}},
+ )
+
+ # Store figure as JSON-serializable dict
+ models_data[model_name]["figures"][metric_key] = json.loads(
+ fig.to_json()
+ )
+
+ # Save to file
+ Path(filename).parent.mkdir(parents=True, exist_ok=True)
+ with open(filename, "w", encoding="utf8") as f:
+ dump(data_bundle, f)
+
+ return data_bundle
+
+ return wrapper
+
+ return decorator
+
+
+def plot_hist(
+ title: str | None = None,
+ x_label: str | None = None,
+ y_label: str | None = None,
+ hoverdata: dict | None = None,
+ filename: str = "histogram.json",
+ nbins: int = 50,
+ bin_range: tuple[float, float] | None = None,
+) -> Callable:
+ """
+ Plot histogram of MLIP results against reference data.
+
+ Parameters
+ ----------
+ title
+ Graph title.
+ x_label
+ Label for x-axis. Default is `None`.
+ y_label
+ Label for y-axis. Default is `None`.
+ hoverdata
+ Hover data dictionary. Default is `{}`.
+ filename
+ Filename to save plot as JSON. Default is "parity.json".
+ nbins
+ Number of bins for histogram. Default is 50.
+ bin_range
+ Tuple specifying the range of bins (min, max). Default is `None`
+ (automatically determined).
+
+ Returns
+ -------
+ Callable
+ Decorator to wrap function.
+ """
+
+ def plot_hist_decorator(func: Callable) -> Callable:
+ """
+ Decorate function to plot histogram.
+
+ Parameters
+ ----------
+ func
+ Function being wrapped.
+
+ Returns
+ -------
+ Callable
+ Wrapped function.
+ """
+
+ @functools.wraps(func)
+ def plot_hist_wrapper(*args, **kwargs) -> dict[str, Any]:
+ """
+ Wrap function to plot histogram.
+
+ Parameters
+ ----------
+ *args
+ Arguments to pass to the function being wrapped.
+ **kwargs
+ Key word arguments to pass to the function being wrapped.
+
+ Returns
+ -------
+ dict
+ Results dictionary.
+ """
+ results = func(*args, **kwargs)
+
+ hovertemplate = "Bin: %{x}
" + "Density: %{y}
"
+
+ customdata = []
+ if hoverdata:
+ for i, key in enumerate(hoverdata):
+ hovertemplate += f"{key}: %{{customdata[{i}]}}
"
+ customdata = list(zip(*hoverdata.values(), strict=True))
+
+ fig = go.Figure()
+ for mlip, value in results.items():
+ fig.add_trace(
+ go.Scatter(
+ x=value["bins"],
+ y=value["hist"],
+ name=mlip,
+ mode="lines",
+ customdata=customdata,
+ hovertemplate=hovertemplate,
+ )
+ )
+
+ fig.update_layout(
+ title={"text": title},
+ xaxis={"title": {"text": x_label}},
+ yaxis={"title": {"text": y_label}},
+ )
+
+ fig.update_traces()
+
+ # Write to file
+ Path(filename).parent.mkdir(parents=True, exist_ok=True)
+ fig.write_json(filename)
+
+ return results
+
+ return plot_hist_wrapper
+
+ return plot_hist_decorator
diff --git a/ml_peg/analysis/aqueous_solutions/ice/metrics.yml b/ml_peg/analysis/aqueous_solutions/ice/metrics.yml
new file mode 100644
index 000000000..88ca21e34
--- /dev/null
+++ b/ml_peg/analysis/aqueous_solutions/ice/metrics.yml
@@ -0,0 +1,19 @@
+metrics:
+ rdf_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: RDF d score
+ level_of_theory: PBE-D3
+ vdos_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: vdos_score
+ level_of_theory: PBE-D3
+ vacf_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: vacf_score
+ level_of_theory: PBE-D3
diff --git a/ml_peg/analysis/surfaces/copper_water_interface/aml.py b/ml_peg/analysis/surfaces/copper_water_interface/aml.py
new file mode 100644
index 000000000..638b73bad
--- /dev/null
+++ b/ml_peg/analysis/surfaces/copper_water_interface/aml.py
@@ -0,0 +1,918 @@
+"""Analysis module for copper water interface calculations."""
+
+from __future__ import annotations
+
+import pickle
+
+from ase.io import read
+import matplotlib.pyplot as plt
+import mdtraj as mdt
+import numpy as np
+from scipy import signal
+
+
+def _acfs_to_spectra(
+ acfs: np.ndarray,
+ nw: int,
+ npad: int = 0,
+ d: float = 1.0,
+ f_w: callable = np.hanning,
+) -> tuple[np.ndarray, np.ndarray]:
+ """
+ Calculate spectra from autocorrelation functions using FFT.
+
+ Optionally processes multiple spectra at the same time. In that case,
+ `acfs` is a 2D array of shape number of ACFs by length of ACFs. This is a
+ low-level function, use `get_spectra` for a more convenient interface.
+
+ Parameters
+ ----------
+ acfs
+ Array, 1D or 2D, symmetric full ACFs.
+ nw
+ One-sided number of points of ACF window.
+ npad
+ One-sided number of additional padding zeros. Default is 0.
+ d
+ Real-space step. Default is 1.0.
+ f_w
+ Function to evaluate the double-sided symmetric window. Default is np.hanning.
+
+ Returns
+ -------
+ tuple
+ Frequency and intensity arrays.
+ """
+ # Make sure we're processing a 2D array.
+ ndim = len(acfs.shape)
+ if ndim == 1:
+ acfs = acfs[np.newaxis, :]
+ elif ndim == 2:
+ pass
+ else:
+ raise ValueError("1D or 2D array required.")
+
+ # number of spectra, total length of full ACF
+ n, length = acfs.shape
+
+ # window width
+ ww = 2 * nw + 1
+
+ assert ww <= length, "Window cannot be wider than data."
+
+ # slice ACF data
+ data = acfs[:, length // 2 - nw : length // 2 + nw + 1].copy()
+ length_trim = data.shape[1]
+
+ # multiply by the window
+ data *= f_w(ww)
+
+ # pad with optional zeros along time axis
+ # one extra zero for symmetry - keep the ACF an even function
+ data = np.pad(data, ((0, 0), (npad + 1, npad)), "constant", constant_values=0.0)
+ assert data.shape == (n, length_trim + 2 * npad + 1)
+
+ # window width including zero padding
+ wwp = data.shape[1]
+
+ # frequencies, with the provided real-space step
+ frequency = np.fft.rfftfreq(wwp, d=d)
+
+ # FFT ACF to spectrum
+ # N.B.: For an ACF that is an even function, imaginary part is strictly zero.
+ # This is general, though.
+ data_fft = np.fft.rfft(data)
+ intensity = np.abs(data_fft)
+
+ # Make result consistent with input in 1D case.
+ if ndim == 1:
+ intensity = intensity[0, :]
+
+ # Normalize intensities to 1:
+ intensity = intensity / intensity.sum()
+
+ return frequency, intensity
+
+
+def get_acfs(source: list[np.ndarray]) -> np.ndarray:
+ """
+ Calculate averaged autocorrelation function for a number of timeseries.
+
+ The `source` yields individual timeseries and each of those is a
+ timeseries of vector quantity. This means that if you
+ want only a single autocorrelation function, you need to wrap the input
+ array in something iterable, like a list.
+
+ Parameters
+ ----------
+ source
+ Iterator over timeseries of dimension N by 3.
+
+ Returns
+ -------
+ ndarray
+ ACFs, as many as timeseries yielded by `source`.
+ """
+ acfs = []
+ for data in source:
+ n = len(data[:, 0])
+ norm = n - np.abs(np.arange(1 - n, n), dtype=float)
+ cfs = [
+ signal.correlate(data[:, d], data[:, d], mode="full", method="auto") / norm
+ for d in range(3)
+ ]
+ acfs.append(np.array(cfs).sum(axis=0))
+ return np.array(acfs).mean(axis=0)
+
+
+def get_spectra(
+ acfs: np.ndarray,
+ dt: float,
+ dt_window: float,
+ dt_pad: float = 0.0,
+ f_w: callable = np.hanning,
+) -> tuple[np.ndarray, np.ndarray]:
+ """
+ Calculate spectra from autocorrelation functions using FFT.
+
+ Processes multiple spectra at the same time, depending on the data in `acfs`.
+
+ Parameters
+ ----------
+ acfs
+ CFs numpy array.
+ dt
+ Time step, in femtoseconds.
+ dt_window
+ Total (double-sided) width of window, in femtoseconds.
+ dt_pad
+ Additional (double-sided) width of padding, in femtoseconds. Default is 0.0.
+ f_w
+ Function used to generate a (symmetric) window. Default is np.hanning.
+
+ Returns
+ -------
+ tuple
+ Frequency (nu) and intensity arrays.
+ """
+ c = 299792458.0 # m / s
+
+ # check the input
+ if dt_window <= 0.0:
+ raise ValueError("`Dt` must be positive.")
+ if dt_pad < 0.0:
+ raise ValueError("`Dt_pad` must not be negative.")
+ if dt * len(acfs) < dt_window:
+ msg = (
+ "The window ({:.0f} fs) must be narrower than the data "
+ "({:.0f} fs). Alas, it is not."
+ )
+ raise ValueError(msg.format(dt_window, dt * len(acfs)))
+
+ nw = int(dt_window / dt / 2.0)
+ npad = int(dt_pad / dt / 2.0)
+
+ frequency, intensity = _acfs_to_spectra(acfs, nw, npad=npad, d=1e-15 * dt, f_w=f_w)
+
+ # convert frequency from Hz to cm^-1
+ nu = frequency / (100.0 * c)
+
+ return nu, intensity
+
+
+def get_unique_atom_types(topology: mdt.Topology) -> list[str]:
+ """
+ Determine the unique atom types in a trajectory.
+
+ Parameters
+ ----------
+ topology
+ Topology object from mdtraj trajectory.
+
+ Returns
+ -------
+ list
+ List of unique atom type names.
+ """
+ return list({atom.name for atom in topology.atoms})
+
+
+def get_unique_elements(topology: mdt.Topology) -> list[str]:
+ """
+ Determine the unique elements in a trajectory.
+
+ Parameters
+ ----------
+ topology
+ Topology object from mdtraj trajectory.
+
+ Returns
+ -------
+ list
+ List of unique element symbols.
+ """
+ return list({atom.element.symbol for atom in topology.atoms})
+
+
+def compute_all_errors(
+ ref_fnc: dict[str, tuple[np.ndarray, np.ndarray]],
+ test_fnc: dict[str, tuple[np.ndarray, np.ndarray]],
+) -> dict[str, list]:
+ """
+ Compute MAEs relative to reference data.
+
+ Given two sets of functions returns the mean absolute error
+ of the test functions relative to the reference (first argument).
+
+ Parameters
+ ----------
+ ref_fnc
+ Reference functions dictionary.
+ test_fnc
+ Test functions dictionary.
+
+ Returns
+ -------
+ dict
+ Dictionary of errors with MAE values for each pair.
+ """
+ error = {}
+ for name, data in ref_fnc.items():
+ # Rescale array in case of different resolution
+ test_data = np.interp(data[0], test_fnc[name][0], test_fnc[name][1])
+ diff = data[1] - test_data
+ mae = np.sum(np.absolute(diff)) / (np.sum(data[1]) + np.sum(test_data))
+ error[name] = [data[0], diff, mae]
+ return error
+
+
+def print_errors(error: dict[str, list]) -> None:
+ """
+ Print the errors in a human readable way.
+
+ Parameters
+ ----------
+ error
+ Dictionary of errors with MAE values.
+ """
+ n = 22
+ print(n * "=")
+ print(f"{'Score Summary':{n}s}")
+ print(n * "=")
+ print("Label | Accuracy [%]")
+ print(n * "_")
+
+ all_err = []
+ for name, data in error.items():
+ err = (1 - data[2]) * 100
+ print(f"{name:7s} | {err:3.4}")
+ all_err.append(err)
+
+ # Mean of errors
+ name = "Mean"
+ err = np.mean(all_err)
+ print(f"{name:7s} | {err:3.4}")
+
+ print(n * "=")
+
+
+def plot_all_f_and_errors(
+ ref: dict[str, tuple[np.ndarray, np.ndarray]],
+ test: dict[str, tuple[np.ndarray, np.ndarray]],
+ error: dict[str, list],
+ observable: str,
+) -> None:
+ """
+ Loop over all functions and plot them, along with the error.
+
+ Parameters
+ ----------
+ ref
+ Reference functions dictionary.
+ test
+ Test functions dictionary.
+ error
+ Error dictionary.
+ observable
+ Observable name for plotting (e.g., "RDF", "VDOS").
+ """
+ for name, ref_data in ref.items():
+ plot_f_and_errors(ref_data, test[name], error[name], name, observable)
+
+
+def plot_f_and_errors(
+ ref: tuple[np.ndarray, np.ndarray],
+ test: tuple[np.ndarray, np.ndarray],
+ error: list,
+ title: str,
+ observable: str,
+) -> None:
+ """
+ Handle the plotting of the functions and their errors.
+
+ Parameters
+ ----------
+ ref
+ Reference function data.
+ test
+ Test function data.
+ error
+ Error data.
+ title
+ Title for the plot.
+ observable
+ Observable name for plotting (e.g., "RDF", "VDOS").
+ """
+ # Plot settings
+ cm2in = 1 / 2.54
+ fig = plt.figure(figsize=(8 * cm2in, 12 * cm2in), constrained_layout=True)
+ gs = fig.add_gridspec(ncols=1, nrows=2, height_ratios=[2.0, 1.0])
+
+ ax0 = fig.add_subplot(gs[0, 0])
+ ax1 = fig.add_subplot(gs[1, 0])
+
+ # Plot reference and test property
+ ax0.plot(ref[0], ref[1], color="black", label="Reference " + str(title), lw=2)
+ ax0.plot(
+ test[0],
+ test[1],
+ color="red",
+ dashes=(0.5, 1.5),
+ dash_capstyle="round",
+ label="Test " + str(title),
+ lw=2,
+ )
+
+ # Plot error
+ ax1.plot(error[0], error[1], color="black", lw=2)
+
+ # Formatting
+ ax0.set_ylabel(observable)
+ ax0.set_xticklabels([])
+ ax1.set_ylabel("Absolute Error")
+ if observable == "VDOS":
+ ax0.set_ylim(ymin=0)
+ ax0.set_xlim([0, 4500])
+ ax1.set_xlim([0, 4500])
+ ax1.set_xlabel(r"Frequency (cm$^{-1}$)")
+ if observable == "RDF":
+ ax1.set_xlabel(r"Distance ($\mathrm{\AA{}}$)")
+
+ ax0.set_title("Species: " + str(title))
+
+ plt.savefig(observable + "-" + str(title) + ".pdf")
+
+
+def plot_mae_errors(error: dict[str, list], fn_out: str = "accuracy-all.pdf") -> None:
+ """
+ Plot the summed absolute errors for each element.
+
+ Parameters
+ ----------
+ error
+ Dictionary of errors with MAE values.
+ fn_out
+ Output filename for the plot. Default is "accuracy-all.pdf".
+ """
+
+ def autolabel(rects: list, form: str = r"{:1.1f}") -> None:
+ """
+ Attach a text label in each bar in rects, displaying its value.
+
+ Parameters
+ ----------
+ rects
+ Bar rectangles from matplotlib.
+ form
+ Format string for label. Default is r"{:1.1f}".
+ """
+ for rect in rects:
+ width = rect.get_width()
+ plt.annotate(
+ form.format(width),
+ xy=(0.0, rect.get_y() + rect.get_height() / 2),
+ xytext=(3, 0), # 3 points vertical offset
+ textcoords="offset points",
+ ha="left",
+ va="center",
+ color="w",
+ fontsize=8,
+ fontweight="bold",
+ )
+
+ # Plot settings
+ cm2in = 1 / 2.54
+ cm = plt.cm.viridis(np.linspace(0, 1.0, 8))[::-1]
+ fig, ax = plt.subplots(
+ ncols=1, nrows=1, constrained_layout=True, figsize=(8 * cm2in, 6 * cm2in)
+ )
+
+ # height of the bars
+ height = 0.6
+ # Label and their locations
+ y = np.arange(len(error) + 1)
+ labels = list(error.keys())
+
+ # Convert errors to percent
+ errors = np.array([(1 - error[key][2]) * 100 for key in labels][::-1])
+
+ # Plot individual errors and mean
+ rects = ax.barh(y[1:], errors, height, color=cm[4])
+ autolabel(rects)
+ rects = ax.barh(y[0], errors.mean(), height, color=cm[6])
+ autolabel(rects)
+
+ # Formatting
+ ax.set_yticks(y)
+ ax.set_yticklabels(np.append(labels, "All")[::-1])
+ ax.set_xlim([0, 100])
+ ax.set_xlabel("Accuracy (%)")
+ ax.set_frame_on(False)
+ ax.grid(axis="x")
+
+ if fn_out is not None:
+ plt.savefig(fn_out)
+
+
+def run_vdos_test(
+ ref_trj: mdt.Trajectory,
+ ref_dt: float,
+ test_trj: mdt.Trajectory,
+ test_dt: float,
+ fn_out: str = "vdos-res.pkl",
+) -> None:
+ """
+ Perform the VDOS scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ ref_dt
+ Reference time step.
+ test_trj
+ Test trajectory.
+ test_dt
+ Test time step.
+ fn_out
+ Output filename for results. Default is "vdos-res.pkl".
+ """
+ # Compute all RDFs
+ ref_vdos = compute_all_vdos(ref_trj, ref_dt)
+ test_vdos = compute_all_vdos(test_trj, test_dt)
+
+ # Compute the errors
+ vdos_errors = compute_all_errors(ref_vdos, test_vdos)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_vdos, test_vdos, vdos_errors, observable="VDOS")
+ plot_mae_errors(vdos_errors, fn_out="vdos-all.pdf")
+
+ # Print the errors
+ print_errors(vdos_errors)
+
+ # Save results
+ results = {"ref_vdos": ref_vdos, "test_vdos": test_vdos, "vdos_errors": vdos_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def run_vdos_single(
+ ref_trj: mdt.Trajectory,
+ ref_dt: float,
+ fn_out: str = "vdos-res.pkl",
+) -> None:
+ """
+ Perform the VDOS scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ ref_dt
+ Reference time step.
+ fn_out
+ Output filename for results. Default is "vdos-res.pkl".
+ """
+ # Compute all RDFs
+ ref_vdos = compute_all_vdos(ref_trj, ref_dt)
+
+ for name, ref_data in ref_vdos.items():
+ # Plot settings
+ cm2in = 1 / 2.54
+ fig = plt.figure(figsize=(8 * cm2in, 6 * cm2in), constrained_layout=True)
+ gs = fig.add_gridspec(ncols=1, nrows=1)
+
+ ax0 = fig.add_subplot(gs[0, 0])
+
+ # Plot reference and test property
+ ax0.plot(ref_data[0], ref_data[1], color="black", lw=2)
+
+ # Formatting
+ ax0.set_ylabel("vdos")
+ ax0.set_xticklabels([])
+ ax0.set_ylim(ymin=0)
+ ax0.set_xlim([0, 4500])
+ ax0.set_title("Species: " + str(name))
+
+ plt.savefig("VDOS-single-" + str(name) + ".pdf")
+
+
+def compute_all_vdos(
+ trj: mdt.Trajectory,
+ dt: float = 1,
+ dt_window: float = 2000.0,
+ dt_pad: float = 2000.0,
+) -> dict[str, tuple[np.ndarray, np.ndarray]]:
+ """
+ Compute VDOS separately for all atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj
+ MDTraj trajectory object.
+ dt
+ Time step. Default is 1.
+ dt_window
+ Total window width. Default is 2000.0.
+ dt_pad
+ Padding width. Default is 2000.0.
+
+ Returns
+ -------
+ dict
+ Dictionary of VDOS data for each atom type.
+ """
+ top = trj.topology
+
+ vdos_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(top)
+
+ for t1 in atom_types:
+ # select indices of the atom type
+ idx_t1 = top.select("name " + t1)
+
+ # calculate velocity autocorrelation functions,
+ # averaged over atoms of this species
+ cfs = get_acfs(trj.xyz.transpose(1, 0, 2)[idx_t1])
+
+ # calculate the spectrum for this species and store it
+ nu, intensity = get_spectra(
+ cfs,
+ dt=dt,
+ dt_window=dt_window,
+ dt_pad=dt_pad,
+ )
+ vdos_all[t1] = nu, intensity
+
+ return vdos_all
+
+
+def parse_velocities_all(filename: str) -> list:
+ """
+ Read velocities from an extended XYZ with momenta using ASE.
+
+ Reads an extended XYZ with momenta using ASE and returns
+ per-frame velocities calculated as momenta / mass.
+
+ Parameters
+ ----------
+ filename
+ Path to the XYZ file.
+
+ Returns
+ -------
+ list
+ List of structures with velocities.
+ """
+ traj = read(filename, index=":") # read all frames
+ structures = []
+
+ for atoms in traj:
+ momenta = atoms.get_momenta() # (N, 3)
+ masses = atoms.get_masses()[:, None] # (N, 1) for broadcasting
+ velocities = momenta / masses # v = p / m
+
+ symbols = atoms.get_chemical_symbols()
+
+ frame = [
+ (sym, v[0], v[1], v[2]) for sym, v in zip(symbols, velocities, strict=False)
+ ]
+ structures.append(frame)
+
+ return structures
+
+
+def write_velocities_traj_all(structures: list, output_file: str) -> None:
+ """
+ Write velocities trajectory to file.
+
+ Parameters
+ ----------
+ structures
+ List of structures with velocities.
+ output_file
+ Path to output file.
+ """
+ with open(output_file, "w") as file:
+ for structure in structures:
+ file.write(f"{len(structure)}\n")
+ file.write('Properties=species:S:1:vel:R:3 pbc="T T T"\n')
+ for atom_name, vx, vy, vz in structure:
+ file.write(f"{atom_name:2s} {vx:12.7f} {vy:12.7f} {vz:12.7f}\n")
+
+
+def compute_all_rdfs(
+ trj: mdt.Trajectory,
+ n_bins: int = 150,
+ **kwargs,
+) -> dict[str, tuple[np.ndarray, np.ndarray]]:
+ """
+ Compute RDFs between all pairs of atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj
+ MDTraj trajectory object.
+ n_bins
+ Number of bins for RDF calculation. Default is 150.
+ **kwargs
+ Additional keyword arguments passed to mdt.compute_rdf.
+
+ Returns
+ -------
+ dict
+ Dictionary of RDF data for each atom type pair.
+ """
+ top = trj.topology
+
+ rdfs_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(trj.topology)
+
+ for i1, t1 in enumerate(atom_types):
+ # select indices of the first atom type
+ idx_t1 = top.select("name " + t1)
+
+ # unique atom type pairs only
+ for i2 in range(i1, len(atom_types)):
+ t2 = atom_types[i2]
+
+ # select indices of the second atom type
+ idx_t2 = top.select("name " + t2)
+
+ # prepare all pairs of indices
+ pairs = trj.topology.select_pairs(idx_t1, idx_t2)
+
+ # single atom with itself -> no RDF
+ if len(pairs) == 0:
+ continue
+
+ # OM: not sure this should be done here
+ min_dimension = trj[0].unitcell_lengths.min() / 2
+
+ r, g_r = mdt.compute_rdf(
+ trj, pairs, (0, min_dimension), n_bins=n_bins, **kwargs
+ )
+
+ rdfs_all[t1 + "-" + t2] = r, g_r
+
+ return rdfs_all
+
+
+def run_rdf_test(
+ ref_trj: mdt.Trajectory,
+ test_trj: mdt.Trajectory,
+ fn_out: str = "rdf-res.pkl",
+) -> None:
+ """
+ Perform the RDF scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj
+ Reference trajectory.
+ test_trj
+ Test trajectory.
+ fn_out
+ Output filename for results. Default is "rdf-res.pkl".
+ """
+ # Compute all RDFs
+ ref_rdf = compute_all_rdfs(ref_trj)
+ test_rdf = compute_all_rdfs(test_trj)
+
+ # Compute the errors
+ rdf_errors = compute_all_errors(ref_rdf, test_rdf)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_rdf, test_rdf, rdf_errors, observable="RDF")
+ plot_mae_errors(rdf_errors, fn_out="rdf-all.pdf")
+
+ # Print the errors
+ print_errors(rdf_errors)
+
+ # Save results
+ results = {"ref_rdf": ref_rdf, "test_rdf": test_rdf, "rdf_errors": rdf_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def load_with_cell(
+ filename_or_filenames: str | list[str],
+ start: int | None = None,
+ stop: int | None = None,
+ step: int | None = None,
+ **kwargs,
+) -> mdt.Trajectory:
+ """
+ Load trajectory and inject cell dimensions from topology PDB file if not present.
+
+ All arguments and keyword arguments are passed on to `mdtraj.load`. The `top`
+ keyword argument is used to load a PDB file and get cell information from it.
+
+ Parameters
+ ----------
+ filename_or_filenames
+ Filename or list of filenames to load.
+ start
+ Starting frame index. Default is None.
+ stop
+ Stopping frame index. Default is None.
+ step
+ Frame step. Default is None.
+ **kwargs
+ Additional keyword arguments passed to mdtraj.load.
+
+ Returns
+ -------
+ mdtraj.Trajectory
+ Loaded trajectory with cell information.
+ """
+ # load the "topology frame" to get cell dimensions
+ top = kwargs.get("top")
+ if top is not None and isinstance(top, str):
+ # load first frame from file as topology
+ frame_top = mdt.load_frame(top, 0)
+ unitcell_lengths = frame_top.unitcell_lengths
+ unitcell_angles = frame_top.unitcell_angles
+ if (unitcell_lengths is None) or (unitcell_angles is None):
+ raise ValueError("Frame providing topology is missing cell information.")
+ else:
+ raise ValueError("Provide a PDB with cell dimensions.")
+
+ # load the trajectory itself
+ trj = mdt.load(filename_or_filenames, **kwargs)
+ trj = trj[start:stop:step]
+
+ # inject the cell information
+ len_trj = len(trj)
+ trj.unitcell_lengths = unitcell_lengths.repeat(len_trj, axis=0)
+ trj.unitcell_angles = unitcell_angles.repeat(len_trj, axis=0)
+
+ return trj
+
+
+def error_score_percentage(mae: float) -> float:
+ """
+ Calculate error score as a percentage from mean absolute error.
+
+ Parameters
+ ----------
+ mae
+ Mean absolute error value.
+
+ Returns
+ -------
+ float
+ Error score as a percentage (0-100).
+ """
+ return (1 - mae) * 100
+
+
+############################
+### NEW FUNCTIONS FOR VACFS
+############################
+
+
+def compute_all_errors_vacf(ref_fnc, test_fnc):
+ """
+ Compute MAEs relative to reference data.
+
+ Given two sets of functions returns the mean absolute error
+ of the test functions relative to the reference (first argument).
+
+ Parameters
+ ----------
+ ref_fnc : dict
+ Reference function data.
+ test_fnc : dict
+ Test function data.
+
+ Returns
+ -------
+ dict
+ Dictionary containing error data for each function.
+ """
+ error = {}
+ for name, data in ref_fnc.items():
+ # Rescale array in case of different resolution
+ test_data = np.interp(data[0], test_fnc[name][0], test_fnc[name][1])
+ diff = data[1] - test_data
+ mae = np.sum(np.abs(diff)) / (
+ np.sum(np.abs(data[1])) + np.sum(np.abs(test_data))
+ )
+ error[name] = [data[0], diff, mae]
+ return error
+
+
+def run_vacfs_test(ref_trj, ref_dt, test_trj, test_dt, fn_out="vcaf-res.pkl"):
+ """
+ Perform the VCAF scoring and save results.
+
+ Parameters
+ ----------
+ ref_trj : mdtraj.Trajectory
+ Reference trajectory.
+ ref_dt : float
+ Reference trajectory time step.
+ test_trj : mdtraj.Trajectory
+ Test trajectory.
+ test_dt : float
+ Test trajectory time step.
+ fn_out : str, default "vcaf-res.pkl"
+ Output filename for results.
+ """
+ # Compute all RDFs
+ ref_vacf = compute_all_vacfs(ref_trj, ref_dt)
+ test_vacf = compute_all_vacfs(test_trj, test_dt)
+
+ # Compute the errors
+ vacf_errors = compute_all_errors_vacf(ref_vacf, test_vacf)
+
+ # Plot the errors
+ plot_all_f_and_errors(ref_vacf, test_vacf, vacf_errors, observable="VACF")
+ plot_mae_errors(vacf_errors, fn_out="vacfs-all.pdf")
+
+ # Print the errors
+ print_errors(vacf_errors)
+
+ # Save results
+ results = {"ref_vacf": ref_vacf, "test_vacf": test_vacf, "vacf_errors": vacf_errors}
+ with open(fn_out, "wb") as f_out:
+ pickle.dump(results, f_out)
+
+
+def compute_all_vacfs(trj, dt=1):
+ """
+ Compute VDOS separately for all atom types in a trajectory.
+
+ Parameters
+ ----------
+ trj : mdtraj.Trajectory
+ Trajectory data.
+ dt : float, default 1
+ Time step.
+
+ Returns
+ -------
+ dict
+ Dictionary containing VACF data for all atom types.
+ """
+ top = trj.topology
+
+ vacfs_all = {}
+
+ # Determine the unique atom types
+ atom_types = get_unique_atom_types(top)
+
+ for t1 in atom_types:
+ # select indices of the atom type
+ idx_t1 = top.select("name " + t1)
+
+ # velocities assumed in Å/fs
+ # shape: (n_frames, n_atoms, 3)
+ vel = trj.xyz.transpose(1, 0, 2)[idx_t1]
+
+ # compute velocity autocorrelation
+ # expected shape: (n_lags,)
+ vacf = get_acfs(vel)
+
+ # time axis
+ t = np.arange(len(vacf)) * dt # fs
+
+ # center index
+ i0 = len(vacf) // 2
+
+ # keep only t >= 0
+ vacf = vacf[i0:]
+ t = t[: len(vacf)]
+
+ # normalize to sort out any units missmatch
+ vacf /= vacf[0]
+
+ vacfs_all[t1] = (t, vacf)
+
+ return vacfs_all
diff --git a/ml_peg/analysis/surfaces/copper_water_interface/analyse_copper_water_interface.py b/ml_peg/analysis/surfaces/copper_water_interface/analyse_copper_water_interface.py
new file mode 100644
index 000000000..9e960906f
--- /dev/null
+++ b/ml_peg/analysis/surfaces/copper_water_interface/analyse_copper_water_interface.py
@@ -0,0 +1,915 @@
+"""Analysis of copper water interface benchmark."""
+
+from __future__ import annotations
+
+from pathlib import Path
+import pickle
+
+from ase.io import read
+import mdtraj as mdt
+import numpy as np
+import pytest
+
+from ml_peg.analysis.surfaces.copper_water_interface import aml
+from ml_peg.analysis.surfaces.copper_water_interface.decorators import (
+ cell_to_bar,
+ plot_hist,
+)
+from ml_peg.analysis.utils.decorators import (
+ build_table,
+)
+from ml_peg.analysis.utils.utils import load_metrics_config
+from ml_peg.app import APP_ROOT
+from ml_peg.calcs import CALCS_ROOT
+from ml_peg.calcs.utils.utils import download_s3_data
+from ml_peg.models.get_models import get_model_names
+from ml_peg.models.models import current_models
+
+MODELS = get_model_names(current_models)
+CALC_PATH = CALCS_ROOT / "surfaces" / "copper_water_interface" / "outputs"
+OUT_PATH = APP_ROOT / "data" / "surfaces" / "copper_water_interface"
+RDF_CURVE_PATH = OUT_PATH / "rdf_curves"
+VDOS_CURVE_PATH = OUT_PATH / "vdos_curves"
+VACF_CURVE_PATH = OUT_PATH / "vacf_curves"
+
+
+METRIC_LABELS = {
+ "rdf_score": "RDF Score",
+ "vdos_score": "VDOS Score",
+ "vacf_score": "VACF Score",
+ "stdev_dipole_z_deviation": "Dipole Moment Stdev Deviation",
+}
+METRICS_CONFIG_PATH = Path(__file__).with_name("metrics.yml")
+DEFAULT_THRESHOLDS, DEFAULT_TOOLTIPS, DEFAULT_WEIGHTS = load_metrics_config(
+ METRICS_CONFIG_PATH
+)
+
+DATA_PATH = (
+ download_s3_data(
+ filename="copper_water_interface.zip",
+ key="inputs/surfaces/copper_water_interface/copper_water_interface.zip",
+ )
+ / "copper_water_interface"
+)
+REF_VEL_PATH = DATA_PATH / "pbe-d3-md-vel.xyz"
+REF_DIPOLE_PATH = DATA_PATH / "ref_dipole_data.npy"
+
+
+def get_rdf_keys() -> list:
+ """
+ Return list of relevant RDF key names.
+
+ Returns
+ -------
+ list
+ List of all RDF keys.
+ """
+ rdf_keys = []
+ xyz_file = DATA_PATH / "init.xyz"
+ atoms = read(xyz_file)
+ all_species = set(atoms.get_chemical_symbols())
+ all_species = sorted(all_species)
+ for species1 in all_species:
+ for species2 in all_species:
+ pair = "-".join(sorted([species1, species2]))
+ if pair not in rdf_keys:
+ rdf_keys.append(pair)
+ return rdf_keys
+
+
+def get_elements() -> list:
+ """
+ Return list of relevant element names.
+
+ Returns
+ -------
+ list
+ List of all elements.
+ """
+ elements = set()
+ xyz_file = DATA_PATH / "init.xyz"
+ atoms = read(xyz_file)
+ for symbol in atoms.get_chemical_symbols():
+ elements.add(symbol)
+ return sorted(elements)
+
+
+@pytest.fixture
+def created_rdfs() -> dict[str, dict]:
+ """
+ Create RDFs for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of RDFs for all models.
+ """
+ rdfs = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/rdf_reference.pkl", "rb") as f_in:
+ rdfs["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if rdf curves directory exists, if not create it
+ if not RDF_CURVE_PATH.exists():
+ RDF_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if rdf curves directory exists for model, if not create it
+ if not (RDF_CURVE_PATH / model_name).exists():
+ (RDF_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ position_xyz = model_dir / "md-pos.xyz"
+ if not position_xyz.exists():
+ continue
+
+ test_trj = aml.load_with_cell(position_xyz, top=ref_topology)
+
+ rdfs[model_name] = aml.compute_all_rdfs(test_trj)
+
+ # Make sure keys are in alphabetical order
+ rdfs_keys = list(rdfs[model_name].keys())
+ for key in rdfs_keys:
+ split_key = key.split("-")
+ split_key.sort()
+ altered_key = "-".join(split_key)
+ if altered_key != key:
+ rdfs[model_name][altered_key] = rdfs[model_name].pop(key)
+
+ # Write rdf curves to file for app use
+ with open(RDF_CURVE_PATH / model_name / "rdf_curves.pkl", "wb") as f_out:
+ pickle.dump(rdfs[model_name], f_out)
+
+ return rdfs
+
+
+def plot_rdfs(model: str, element_pair: str, rdf: dict, error: bool = False) -> None:
+ """
+ Plot RDF paths and save all structure files.
+
+ Parameters
+ ----------
+ model
+ Name of MLIP.
+ element_pair
+ Element pair for RDF.
+ rdf
+ RDF data.
+ error
+ Whether to plot error or raw RDF.
+ """
+
+ def plot_rdf() -> dict[str, tuple[list[float], list[float]]]:
+ """
+ Plot a RDF and save the structure file.
+
+ Returns
+ -------
+ dict[str, tuple[list[float], list[float]]]
+ Dictionary of tuples of image/energy for each model.
+ """
+ results = {}
+ results[model] = [
+ rdf[0].tolist(),
+ rdf[1].tolist(),
+ ]
+
+ return results
+
+ plot_rdf()
+
+
+@pytest.fixture
+def rdf_scores(created_rdfs: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average RDF score for all models.
+
+ Parameters
+ ----------
+ created_rdfs
+ Created RDFs for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average RDF scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_rdfs[model_name] is None:
+ continue
+ rdf_errors = aml.compute_all_errors(
+ created_rdfs["ref"], created_rdfs[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ rdf_scores = [
+ aml.error_score_percentage(error[2]) for error in rdf_errors.values()
+ ]
+
+ results[model_name] = rdf_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in rdf_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+def mean_rdf_score(rdf_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean RDF score for all models.
+
+ Parameters
+ ----------
+ rdf_scores
+ Average RDF scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean RDF scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in rdf_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+# -------- VDOS
+
+
+@pytest.fixture
+def created_vdos() -> dict[str, dict]:
+ """
+ Create VDOS for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of VDOS for all models.
+ """
+ vdos = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/vdos_reference.pkl", "rb") as f_in:
+ vdos["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if vdos curves directory exists, if not create it
+ if not VDOS_CURVE_PATH.exists():
+ VDOS_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if vdos curves directory exists for model, if not create it
+ if not (VDOS_CURVE_PATH / model_name).exists():
+ (VDOS_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ vel_xyz = model_dir / "md-velc.xyz"
+ if not vel_xyz.exists():
+ continue
+
+ test_vel = mdt.load(vel_xyz, top=ref_topology, stride=1)
+ test_top = mdt.load_pdb(ref_topology)
+
+ test_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(test_vel), axis=0
+ )
+ test_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(test_vel), axis=0
+ )
+
+ ref_dt = 1
+
+ vdos[model_name] = aml.compute_all_vdos(test_vel, ref_dt)
+
+ # Write rdf curves to file for app use
+ with open(VDOS_CURVE_PATH / model_name / "vdos_curves.pkl", "wb") as f_out:
+ pickle.dump(vdos[model_name], f_out)
+
+ return vdos
+
+
+@pytest.fixture
+def vdos_scores(created_vdos: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average VDOS score for all models.
+
+ Parameters
+ ----------
+ created_vdos
+ Created VDOS for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average VDOS scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_vdos[model_name] is None:
+ continue
+ vdos_errors = aml.compute_all_errors(
+ created_vdos["ref"], created_vdos[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ vdos_scores = [
+ aml.error_score_percentage(error[2]) for error in vdos_errors.values()
+ ]
+ results[model_name] = vdos_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in vdos_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+def mean_vdos_score(vdos_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean VDOS score for all models.
+
+ Parameters
+ ----------
+ vdos_scores
+ Average VDOS scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean VDOS scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in vdos_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+@pytest.fixture
+def stdev_dipole_z_deviation() -> dict[str, dict]:
+ """
+ Get standard deviation difference of dipole moments of water molecules.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of predicted dipole moment standard deviation differences
+ for all models.
+ """
+ dipole_results = {"ref": None} | dict.fromkeys(MODELS)
+ discard = 0
+
+ # Load reference dipole data
+ ref_dipoles = np.load(REF_DIPOLE_PATH)
+ ref_dipole_stdev = np.std(ref_dipoles)
+ dipole_results["ref"] = ref_dipole_stdev
+ print(f"!!!Reference Dipole Stdev: {ref_dipole_stdev}")
+
+ hist_results = {}
+
+ def create_hist(data: np.ndarray) -> tuple[list, list]:
+ """
+ Create histogram data.
+
+ Parameters
+ ----------
+ data
+ Data to create histogram from.
+
+ Returns
+ -------
+ tuple[list, list]
+ Tuple of bins and histogram counts.
+ """
+ bins = np.arange(-0.05, 0.05 + 1e-6, 0.0025)
+ hist, _ = np.histogram(data, bins=bins, density=True)
+ # Index each dipole into the bins
+ indices = np.digitize(data, bins)
+ # Select a dipole from each bin to represent the bin
+ selected_bins = []
+ for i in range(1, len(bins)):
+ bin_indices = np.where(indices == i)[0]
+ if len(bin_indices) > 0:
+ selected_bins.append(data[bin_indices[0]])
+ else:
+ selected_bins.append(np.nan)
+
+ # TODO use to sample structures to visualise later
+
+ return {"bins": bins.tolist(), "hist": hist.tolist(), "indices": selected_bins}
+
+ for model_name in MODELS:
+ # Read dipoles from trajectory, which is stored in info dictionary
+ dipoles_z = np.loadtxt(
+ CALC_PATH / model_name / "md.thermo", usecols=4, skiprows=2 + discard
+ )
+
+ dipole_stdev = np.abs(np.std(dipoles_z) - ref_dipole_stdev)
+ dipole_results[model_name] = dipole_stdev
+ hist_results[model_name] = create_hist(dipoles_z)
+ print(
+ f"!!!Model: {model_name}, Dipole Stdev Deviation: {dipole_stdev},"
+ f" number of samples: {len(dipoles_z)}"
+ )
+
+ # Add reference histogram
+ hist_results["ref"] = create_hist(ref_dipoles)
+
+ return {"stdev_dipole_z_deviation": dipole_results, "hist_data": hist_results}
+
+
+@pytest.fixture
+@plot_hist(
+ filename=OUT_PATH / "figure_hist_dipoles.json",
+ title="Dipole Moment Distribution",
+ x_label="Pz/A [e/Å]",
+ y_label="Density",
+ hoverdata={},
+)
+def build_dipole_histogram(
+ stdev_dipole_z_deviation: dict[str, dict],
+) -> dict[str, dict]:
+ """
+ Build dipole moment histogram data structure.
+
+ Parameters
+ ----------
+ stdev_dipole_z_deviation
+ Standard deviation difference of dipole moments of water molecules.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of histogram data for all models.
+ """
+ return stdev_dipole_z_deviation["hist_data"]
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "rdf_score_bar.json",
+ x_label="X Coord",
+ y_label="RDF Score",
+)
+def build_rdf_interactive_data(
+ rdf_scores: dict[str, list], created_rdfs: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for RDF bar plot.
+
+ Parameters
+ ----------
+ rdf_scores
+ Average RDF scores for all models.
+ created_rdfs
+ Created RDFs for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for RDF bar plot.
+ """
+ # Get all unique RDF pairs from the reference data
+ ref_pairs = list(created_rdfs["ref"].keys()) if created_rdfs["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if rdf_scores.get(model_name) is None or created_rdfs.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_rdfs["ref"]
+ model_rdf_data = created_rdfs[model_name]
+
+ # Get scores for each RDF pair
+ rdf_errors = aml.compute_all_errors(ref_data, model_rdf_data)
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["rdf_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in rdf_errors:
+ error_data = rdf_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_rdf_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "g(r)",
+ "xlabel": "Distance (Å)", # error array
+ "xlim": [0, 0.6],
+ },
+ }
+ )
+ model_data["metrics"]["rdf_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["rdf_score"] = "RDF Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "vdos_score_bar.json",
+ x_label="Element",
+ y_label="VDOS Score",
+)
+def build_vdos_interactive_data(
+ vdos_scores: dict[str, list], created_vdos: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for VDOS bar plot.
+
+ Parameters
+ ----------
+ vdos_scores
+ Average VDOS scores for all models.
+ created_vdos
+ Created VDOS for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for VDOS bar plot.
+ """
+ # Get all unique VDOS pairs from the reference data
+ ref_pairs = list(created_vdos["ref"].keys()) if created_vdos["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if vdos_scores.get(model_name) is None or created_vdos.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_vdos["ref"]
+ model_vdos_data = created_vdos[model_name]
+
+ # Get scores for each VDOS pair
+ vdos_errors = aml.compute_all_errors(ref_data, model_vdos_data)
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["vdos_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in vdos_errors:
+ error_data = vdos_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_vdos_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "Intensity (a.u)",
+ "xlabel": "Frequency (cm⁻¹)", # error array
+ "xlim": [0, 4000],
+ },
+ }
+ )
+ model_data["metrics"]["vdos_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["vdos_score"] = "VDOS Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+# ----------------------+----------------------+---------------------- #
+# ----------------------+-------- VACF --------+---------------------- #
+# ----------------------+----------------------+---------------------- #
+
+
+@pytest.fixture
+def created_vacf() -> dict[str, dict]:
+ """
+ Create VACF for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Dictionary of VACF for all models.
+ """
+ vacf = {"ref": None} | dict.fromkeys(MODELS)
+
+ # Load reference RDF
+ with open(f"{DATA_PATH}/vacf_reference.pkl", "rb") as f_in:
+ vacf["ref"] = pickle.load(f_in)
+
+ # Load topology
+ ref_topology = f"{DATA_PATH}/init.pdb"
+
+ # Check if vacf curves directory exists, if not create it
+ if not VACF_CURVE_PATH.exists():
+ VACF_CURVE_PATH.mkdir(parents=True, exist_ok=True)
+
+ # Load model RDFs
+ for model_name in MODELS:
+ model_dir = CALC_PATH / model_name
+
+ if not model_dir.exists():
+ continue
+
+ # Check if vacf curves directory exists for model, if not create it
+ if not (VACF_CURVE_PATH / model_name).exists():
+ (VACF_CURVE_PATH / model_name).mkdir(parents=True, exist_ok=True)
+
+ vel_xyz = model_dir / "md-velc.xyz"
+ if not vel_xyz.exists():
+ continue
+
+ test_vel = mdt.load(vel_xyz, top=ref_topology, stride=1)
+ # Truncate to same length as reference
+ test_top = mdt.load_pdb(ref_topology)
+
+ test_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(test_vel), axis=0
+ )
+ test_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(test_vel), axis=0
+ )
+
+ ref_dt = 1
+
+ # Check if length of trajectory matches reference
+ ref_length = len(list(vacf["ref"].values())[0][0])
+ test_length = len(test_vel)
+ min_length = min(test_length, ref_length)
+
+ if vacf["ref"] is not None:
+ if test_length != ref_length:
+ # Truncate both to shortest length - and recalculate reference if needed
+
+ test_vel = test_vel[test_length - min_length :]
+ if len(test_vel) != ref_length:
+ ref_vel = mdt.load(REF_VEL_PATH, top=ref_topology, stride=1)
+ ref_vel.unitcell_lengths = np.repeat(
+ test_top.unitcell_lengths, len(ref_vel), axis=0
+ )
+ ref_vel.unitcell_vectors = np.repeat(
+ test_top.unitcell_vectors, len(ref_vel), axis=0
+ )
+ ref_vel_trunc = ref_vel[ref_length - min_length :]
+ vacf_ref_trunc = aml.compute_all_vacfs(ref_vel_trunc, ref_dt)
+ # Write updated reference vacf curves to file for app use
+
+ else:
+ vacf_ref_trunc = vacf["ref"]
+
+ vacf[f"ref_{model_name}"] = vacf_ref_trunc
+ vacf[model_name] = aml.compute_all_vacfs(test_vel, ref_dt)
+
+ # Write rdf curves to file for app use
+ with open(VACF_CURVE_PATH / model_name / "vacf_curves.pkl", "wb") as f_out:
+ pickle.dump(vacf[model_name], f_out)
+
+ return vacf
+
+
+@pytest.fixture
+def vacf_scores(created_vacf: dict[str, dict]) -> dict[str, float]:
+ """
+ Get Average VACF score for all models.
+
+ Parameters
+ ----------
+ created_vacf
+ Created VACF for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Average VACF scores for all models.
+ """
+ results = {"ref": []} | dict.fromkeys(MODELS)
+ store_ref = False
+ for model_name in MODELS:
+ if created_vacf[model_name] is None:
+ continue
+ vacf_errors = aml.compute_all_errors_vacf(
+ created_vacf[f"ref_{model_name}"], created_vacf[model_name]
+ )
+ # Mae is stored per pair in [2] slot of tuple
+ vacf_scores = [
+ aml.error_score_percentage(error[2]) for error in vacf_errors.values()
+ ]
+ results[model_name] = vacf_scores
+ if not store_ref:
+ results["ref"] = [100.0 for _ in vacf_scores]
+
+ store_ref = True
+
+ return results
+
+
+@pytest.fixture
+@cell_to_bar(
+ filename=OUT_PATH / "vacf_score_bar.json",
+ x_label="Element",
+ y_label="VACF Score",
+)
+def build_vacf_interactive_data(
+ vacf_scores: dict[str, list], created_vacf: dict[str, dict]
+) -> dict:
+ """
+ Build interactive data structure for VACF bar plot.
+
+ Parameters
+ ----------
+ vacf_scores
+ Average VACF scores for all models.
+ created_vacf
+ Created VACF for all models.
+
+ Returns
+ -------
+ dict
+ Interactive data structure for VACF bar plot.
+ """
+ # Get all unique VACF pairs from the reference data
+ ref_pairs = list(created_vacf["ref"].keys()) if created_vacf["ref"] else []
+
+ models_data = {}
+
+ for model_name in MODELS:
+ if vacf_scores.get(model_name) is None or created_vacf.get(model_name) is None:
+ continue
+
+ model_data = {}
+ ref_data = created_vacf[f"ref_{model_name}"]
+ model_vacf_data = created_vacf[model_name]
+
+ # Get scores for each VACF pair
+ vacf_errors = aml.compute_all_errors_vacf(ref_data, created_vacf[model_name])
+
+ model_data["metrics"] = {}
+ model_data["metrics"]["vacf_score"] = {}
+ pair_point_list = []
+ for pair in ref_pairs:
+ if pair in vacf_errors:
+ error_data = vacf_errors[pair]
+ d_score = aml.error_score_percentage(error_data[2]) # MAE score
+ pair_point_list.append(
+ {
+ "label": pair,
+ "value": d_score,
+ "data": {
+ "x_values": error_data[0].tolist(), # r values
+ "ref": ref_data[pair][1].tolist(), # reference RDF
+ "pred": model_vacf_data[pair][1].tolist(), # predicted RDF
+ "error": error_data[1].tolist(),
+ "ylabel": "VACF",
+ "xlabel": "Time [fs]", # error array
+ },
+ }
+ )
+ model_data["metrics"]["vacf_score"] = pair_point_list
+ models_data[model_name] = model_data
+
+ # Create metrics mapping
+ metrics = {}
+ metrics["vacf_score"] = "VACF Score"
+
+ return {"models": models_data, "metrics": metrics, "pairs": ref_pairs}
+
+
+@pytest.fixture
+def mean_vacf_score(vacf_scores: dict[str, float]) -> dict[str, float]:
+ """
+ Get Mean VACF score for all models.
+
+ Parameters
+ ----------
+ vacf_scores
+ Average VACF scores for all models.
+
+ Returns
+ -------
+ dict[str, float]
+ Dictionary of Mean VACF scores for all models.
+ """
+ mean_results = {"ref": 100.0} | dict.fromkeys(MODELS)
+ for model_name, scores in vacf_scores.items():
+ if scores is None:
+ continue
+ mean_results[model_name] = np.mean(scores)
+ return mean_results
+
+
+@pytest.fixture
+@build_table(
+ filename=OUT_PATH / "copper_water_interface_metrics_table.json",
+ metric_tooltips=DEFAULT_TOOLTIPS,
+ thresholds=DEFAULT_THRESHOLDS,
+)
+def metrics(
+ mean_rdf_score: dict[str, float],
+ mean_vdos_score: dict[str, float],
+ mean_vacf_score: dict[str, float],
+ stdev_dipole_z_deviation: dict[str, dict],
+ build_dipole_histogram: dict[str, dict],
+) -> dict[str, dict]:
+ """
+ Get all metrics.
+
+ Parameters
+ ----------
+ mean_rdf_score
+ Mean RDF score for all models.
+ mean_vdos_score
+ Mean VDOS score for all models.
+ mean_vacf_score
+ Mean VACF score for all models.
+ stdev_dipole_z_deviation
+ Standard deviation difference of dipole moments for all models.
+ build_dipole_histogram
+ Dipole moment histogram data for all models.
+
+ Returns
+ -------
+ dict[str, dict]
+ Metric names and values for all models.
+ """
+ return {
+ "rdf_score": mean_rdf_score,
+ "vdos_score": mean_vdos_score,
+ "vacf_score": mean_vacf_score,
+ "stdev_dipole_z_deviation": stdev_dipole_z_deviation[
+ "stdev_dipole_z_deviation"
+ ],
+ }
+
+
+def test_copper_water_interface(
+ metrics: dict[str, dict],
+ build_rdf_interactive_data: dict,
+ build_vdos_interactive_data: dict,
+ build_vacf_interactive_data: dict,
+ build_dipole_histogram: dict[str, dict],
+) -> None:
+ """
+ Run copper_water_interface tests.
+
+ Parameters
+ ----------
+ metrics
+ All copper_water_interface metrics.
+ build_rdf_interactive_data
+ Interactive data for RDF bar plot.
+ build_vdos_interactive_data
+ Interactive data for VDOS bar plot.
+ build_vacf_interactive_data
+ Interactive data for VACF bar plot.
+ build_dipole_histogram
+ Dipole moment histogram data for all models.
+ """
+ return
+
+
+"""@plot_parity(
+ filename=OUT_PATH / "figure_rdf_score.json",
+ title="RDF",
+ x_label="Predicted RDF score",
+ y_label="Reference RDF score",
+ hoverdata={'RDF-pair': get_rdf_keys()},
+)"""
diff --git a/ml_peg/analysis/surfaces/copper_water_interface/decorators.py b/ml_peg/analysis/surfaces/copper_water_interface/decorators.py
new file mode 100644
index 000000000..d3c39476d
--- /dev/null
+++ b/ml_peg/analysis/surfaces/copper_water_interface/decorators.py
@@ -0,0 +1,255 @@
+"""Fixtures for MLIP results analysis for copper_water_interface."""
+
+from __future__ import annotations
+
+from collections.abc import Callable
+import functools
+import json
+from json import dump
+from pathlib import Path
+from typing import Any
+
+import plotly.graph_objects as go
+
+
+def cell_to_bar(
+ *,
+ filename: str | Path,
+ x_label: str | None = None,
+ y_label: str | None = None,
+ title_template: str = "{model} - {metric}",
+) -> Callable:
+ """
+ Pre-generate bar plots for each table cell (model-metric pair).
+
+ Use this for benchmarks where each table CELL generates its own bar plot
+ (e.g., clicking MACE's ω_max shows a bar for that specific model-metric
+ pair). For benchmarks where clicking a COLUMN shows all models on one bar
+ (like S24 or OC157), use @plot_parity instead.
+
+ This decorator generates complete Plotly figures during analysis instead of
+ saving raw points for the app to process on-the-fly.
+
+ Parameters
+ ----------
+ filename
+ Path where JSON data with pre-made figures will be saved.
+ x_label
+ Label for x-axis (typically "Score"). Default is None.
+ y_label
+ Label for y-axis (typically "Names of Variables"). Default is None.
+ title_template
+ Template for plot titles with {model} and {metric} placeholders.
+ Default is "{model} - {metric}".
+
+ Returns
+ -------
+ Callable
+ Decorator that wraps analysis functions to pre-generate bar figures.
+ """
+
+ def decorator(func: Callable) -> Callable:
+ """
+ Wrap the decorated callable to pre-generate bar figures.
+
+ Parameters
+ ----------
+ func
+ Analysis function returning the dataset consumed by the Dash app.
+
+ Returns
+ -------
+ Callable
+ Wrapped function that runs ``func`` and emits Plotly figures.
+ """
+
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ """
+ Execute func and generate bar plots for each model-metric pair.
+
+ Parameters
+ ----------
+ *args
+ Positional arguments forwarded to ``func``.
+ **kwargs
+ Keyword arguments forwarded to ``func``.
+
+ Returns
+ -------
+ dict
+ The dataset produced by ``func`` (with ``figures`` entries).
+ """
+ data_bundle = func(*args, **kwargs)
+
+ # Extract metadata
+ metric_labels = data_bundle.get("metrics", {})
+ models_data = data_bundle.get("models", {})
+
+ # Create figures for each model-metric pair
+ for model_name, model_data in models_data.items():
+ model_data["figures"] = {}
+ metrics_data = model_data.get("metrics", {})
+
+ for metric_key, metric_info in metrics_data.items():
+ # Extract ref and pred values
+
+ labels = [minfo["label"] for minfo in metric_info]
+ values = [minfo["value"] for minfo in metric_info]
+
+ # Build hovertemplate
+ hovertemplate = (
+ "Score: %{x}
Ref: %{y}
"
+ "Label: %{customdata[0]}
"
+ )
+ # Create figure
+ fig = go.Figure()
+ fig.add_trace(
+ go.Bar(
+ x=labels,
+ y=values,
+ customdata=[
+ [lab, minfo["data"]]
+ for lab, minfo in zip(labels, metric_info, strict=False)
+ ],
+ hovertemplate=hovertemplate,
+ showlegend=False,
+ )
+ )
+ # Set ylimits as 0 to 105
+ fig.update_yaxes(range=[0, 105])
+
+ # Update layout
+ metric_label = metric_labels.get(metric_key, metric_key)
+ title = title_template.format(model=model_name, metric=metric_label)
+ fig.update_layout(
+ title={"text": title},
+ xaxis={"title": {"text": x_label}},
+ yaxis={"title": {"text": y_label}},
+ )
+
+ # Store figure as JSON-serializable dict
+ models_data[model_name]["figures"][metric_key] = json.loads(
+ fig.to_json()
+ )
+
+ # Save to file
+ Path(filename).parent.mkdir(parents=True, exist_ok=True)
+ with open(filename, "w", encoding="utf8") as f:
+ dump(data_bundle, f)
+
+ return data_bundle
+
+ return wrapper
+
+ return decorator
+
+
+def plot_hist(
+ title: str | None = None,
+ x_label: str | None = None,
+ y_label: str | None = None,
+ hoverdata: dict | None = None,
+ filename: str = "histogram.json",
+ nbins: int = 50,
+ bin_range: tuple[float, float] | None = None,
+) -> Callable:
+ """
+ Plot histogram of MLIP results against reference data.
+
+ Parameters
+ ----------
+ title
+ Graph title.
+ x_label
+ Label for x-axis. Default is `None`.
+ y_label
+ Label for y-axis. Default is `None`.
+ hoverdata
+ Hover data dictionary. Default is `{}`.
+ filename
+ Filename to save plot as JSON. Default is "parity.json".
+ nbins
+ Number of bins for histogram. Default is 50.
+ bin_range
+ Tuple specifying the range of bins (min, max). Default is `None`
+ (automatically determined).
+
+ Returns
+ -------
+ Callable
+ Decorator to wrap function.
+ """
+
+ def plot_hist_decorator(func: Callable) -> Callable:
+ """
+ Decorate function to plot histogram.
+
+ Parameters
+ ----------
+ func
+ Function being wrapped.
+
+ Returns
+ -------
+ Callable
+ Wrapped function.
+ """
+
+ @functools.wraps(func)
+ def plot_hist_wrapper(*args, **kwargs) -> dict[str, Any]:
+ """
+ Wrap function to plot histogram.
+
+ Parameters
+ ----------
+ *args
+ Arguments to pass to the function being wrapped.
+ **kwargs
+ Key word arguments to pass to the function being wrapped.
+
+ Returns
+ -------
+ dict
+ Results dictionary.
+ """
+ results = func(*args, **kwargs)
+
+ hovertemplate = "Bin: %{x}
" + "Density: %{y}
"
+
+ customdata = []
+ if hoverdata:
+ for i, key in enumerate(hoverdata):
+ hovertemplate += f"{key}: %{{customdata[{i}]}}
"
+ customdata = list(zip(*hoverdata.values(), strict=True))
+
+ fig = go.Figure()
+ for mlip, value in results.items():
+ fig.add_trace(
+ go.Scatter(
+ x=value["bins"],
+ y=value["hist"],
+ name=mlip,
+ mode="lines",
+ customdata=customdata,
+ hovertemplate=hovertemplate,
+ )
+ )
+
+ fig.update_layout(
+ title={"text": title},
+ xaxis={"title": {"text": x_label}},
+ yaxis={"title": {"text": y_label}},
+ )
+
+ fig.update_traces()
+
+ # Write to file
+ Path(filename).parent.mkdir(parents=True, exist_ok=True)
+ fig.write_json(filename)
+
+ return results
+
+ return plot_hist_wrapper
+
+ return plot_hist_decorator
diff --git a/ml_peg/analysis/surfaces/copper_water_interface/metrics.yml b/ml_peg/analysis/surfaces/copper_water_interface/metrics.yml
new file mode 100644
index 000000000..c314c1019
--- /dev/null
+++ b/ml_peg/analysis/surfaces/copper_water_interface/metrics.yml
@@ -0,0 +1,25 @@
+metrics:
+ rdf_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: RDF d score
+ level_of_theory: PBE-D3
+ vdos_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: vdos_score
+ level_of_theory: PBE-D3
+ vacf_score:
+ good: 100.0
+ bad: 80.0
+ unit: null
+ tooltip: vacf_score
+ level_of_theory: PBE-D3
+ stdev_dipole_z_deviation:
+ good: 0.0
+ bad: 0.003
+ unit: e/Å
+ tooltip: Difference in Standard Deviation of Dipole Z Deviation
+ level_of_theory: PBE-D3
diff --git a/ml_peg/app/aqueous_solutions/bulk_water/app_bulk_water.py b/ml_peg/app/aqueous_solutions/bulk_water/app_bulk_water.py
new file mode 100644
index 000000000..5709c3586
--- /dev/null
+++ b/ml_peg/app/aqueous_solutions/bulk_water/app_bulk_water.py
@@ -0,0 +1,199 @@
+"""Analysis of bulk water benchmark."""
+
+from __future__ import annotations
+
+import base64
+from io import BytesIO
+
+import matplotlib
+
+matplotlib.use("Agg")
+import json
+
+from dash import Input, Output, callback, dcc, html
+from dash.html import Div
+import matplotlib.pyplot as plt
+
+from ml_peg.app import APP_ROOT
+from ml_peg.app.base_app import BaseApp
+from ml_peg.app.utils.build_callbacks import (
+ plot_from_table_cell,
+)
+from ml_peg.models.get_models import get_model_names
+from ml_peg.models.models import current_models
+
+# Get all models
+MODELS = get_model_names(current_models)
+BENCHMARK_NAME = "Bulk Water"
+DOCS_URL = "https://ddmms.github.io/ml-peg/user_guide/benchmarks/aqueous_solutions/bulk_water.html"
+DATA_PATH = APP_ROOT / "data" / "aqueous_solutions" / "bulk_water"
+METRICS = ["rdf_score", "vdos_score", "vacf_score"]
+
+
+def render_subplot_component(click_data: dict) -> html.Div | None:
+ """
+ Render comparison plot for clicked bar.
+
+ Parameters
+ ----------
+ click_data
+ Click data from bar chart containing data.
+
+ Returns
+ -------
+ html.Div | None
+ Component containing comparison plot.
+ """
+ if not click_data or "points" not in click_data:
+ return html.Div("Click on a bar to see comparison.")
+
+ point = click_data["points"][0]
+ if "customdata" not in point or len(point["customdata"]) < 2:
+ return html.Div(f"No data available: {point.keys()}")
+
+ rdf_data = point["customdata"][1] # Get RDF data from customdata
+ pair_name = point["customdata"][0] # Get pair name
+
+ # Create matplotlib figure
+ fig, axes = plt.subplots(1, 2, figsize=(12, 4))
+ ax1, ax2 = axes
+
+ # Load data
+ x_values = rdf_data["x_values"]
+ ref_values = rdf_data["ref"]
+ pred_values = rdf_data["pred"]
+ error = rdf_data["error"]
+ xlabel = rdf_data["xlabel"]
+ ylabel = rdf_data["ylabel"]
+
+ # Plot Reference and Predicted RDFs
+ ax1.plot(x_values, ref_values, "b-", label="Reference", linewidth=2)
+ ax1.plot(x_values, pred_values, "r--", label="Predicted", linewidth=2)
+ ax1.set_xlabel(xlabel)
+ ax1.set_ylabel(ylabel)
+ ax1.set_title(f"Comparison: {pair_name}")
+ ax1.legend()
+ ax1.grid(True, alpha=0.3)
+
+ # Plot Error
+ ax2.plot(x_values, error, "k-", label="Error", linewidth=2)
+ ax2.set_xlabel(xlabel)
+ ax2.set_ylabel(rf"${{\Delta}}${ylabel}")
+ ax2.set_title("Error")
+ ax2.legend()
+ ax2.grid(True, alpha=0.3)
+
+ # Check if xlim is provided
+ if "xlim" in rdf_data:
+ ax1.set_xlim(rdf_data["xlim"])
+ ax2.set_xlim(rdf_data["xlim"])
+
+ # Convert to base64 for display
+ buffer = BytesIO()
+ plt.tight_layout()
+ plt.savefig(buffer, format="png", dpi=150, bbox_inches="tight")
+ buffer.seek(0)
+ image_base64 = base64.b64encode(buffer.read()).decode()
+ plt.close()
+
+ return html.Div(
+ [
+ html.H4(f"Comparison: {pair_name}"),
+ html.Img(
+ src=f"data:image/png;base64,{image_base64}",
+ style={"maxWidth": "100%", "border": "1px solid #ccc"},
+ ),
+ ]
+ )
+
+
+class BulkWaterApp(BaseApp):
+ """Bulk Water benchmark app layout and callbacks."""
+
+ def register_callbacks(self) -> None:
+ """Register callbacks to app."""
+ # Assets dir will be parent directory - individual files for each system
+
+ cell_plots = {}
+ interactive_data = {}
+
+ # Load the complex interactive data from your @cell_to_bar decorator
+
+ for metric in METRICS:
+ try:
+ with open(DATA_PATH / f"{metric}_bar.json") as f:
+ interactive_data[metric] = json.load(f)
+ except FileNotFoundError:
+ interactive_data[metric] = {"models": {}, "metrics": {}}
+
+ # Extract pre-generated figures for each model-metric pair
+
+ for model_name, model_data in (
+ interactive_data[metric].get("models", {}).items()
+ ):
+ if model_name not in cell_plots:
+ cell_plots[model_name] = {}
+
+ figures = model_data.get("figures", {})
+ for metric_key, figure_data in figures.items():
+ cell_plots[model_name][metric_key] = dcc.Graph(
+ id=f"{BENCHMARK_NAME}-figure-bar-{model_name}",
+ figure=figure_data,
+ )
+
+ print("Cell plots prepared:", cell_plots.keys())
+ plot_from_table_cell(
+ table_id=self.table_id,
+ plot_id=f"{BENCHMARK_NAME}-figure-placeholder",
+ cell_to_plot=cell_plots,
+ )
+ print(cell_plots.keys())
+
+ # Add click callbacks for each model's bar charts
+ for model_name in cell_plots.keys():
+
+ @callback(
+ Output(
+ f"{BENCHMARK_NAME}-figure-plot-container-{model_name}", "children"
+ ),
+ Input(f"{BENCHMARK_NAME}-figure-bar-{model_name}", "clickData"),
+ prevent_initial_call=True,
+ )
+ def show_comparison_plot(click_data):
+ return render_subplot_component(click_data)
+
+
+def get_app() -> BulkWaterApp:
+ """
+ Get Bulk Water benchmark app layout and callback registration.
+
+ Returns
+ -------
+ BulkWaterApp
+ Benchmark layout and callback registration.
+ """
+ extra_components = [
+ Div(id=f"{BENCHMARK_NAME}-figure-placeholder"),
+ Div(
+ id=f"{BENCHMARK_NAME}-figure-bar",
+ children="Click on a metric to see bar plot.",
+ ),
+ Div(
+ id=f"{BENCHMARK_NAME}-figure-plot-container",
+ children="Click on a bar to see comparison.",
+ ),
+ ]
+ for model_name in MODELS:
+ extra_components.append(Div(id=f"{BENCHMARK_NAME}-figure-bar-{model_name}"))
+ extra_components.append(Div(id=f"{BENCHMARK_NAME}-figure-bar-{model_name}"))
+ extra_components.append(
+ Div(id=f"{BENCHMARK_NAME}-figure-plot-container-{model_name}")
+ )
+
+ return BulkWaterApp(
+ name=BENCHMARK_NAME,
+ description="Bulk Water score.",
+ docs_url=DOCS_URL,
+ table_path=DATA_PATH / "bulk_water_metrics_table.json",
+ extra_components=extra_components,
+ )
diff --git a/ml_peg/app/aqueous_solutions/ice/app_ice.py b/ml_peg/app/aqueous_solutions/ice/app_ice.py
new file mode 100644
index 000000000..953b40ab5
--- /dev/null
+++ b/ml_peg/app/aqueous_solutions/ice/app_ice.py
@@ -0,0 +1,201 @@
+"""Analysis of ice benchmark."""
+
+from __future__ import annotations
+
+import base64
+from io import BytesIO
+
+import matplotlib
+
+matplotlib.use("Agg")
+import json
+
+from dash import Input, Output, callback, dcc, html
+from dash.html import Div
+import matplotlib.pyplot as plt
+
+from ml_peg.app import APP_ROOT
+from ml_peg.app.base_app import BaseApp
+from ml_peg.app.utils.build_callbacks import (
+ plot_from_table_cell,
+)
+from ml_peg.models.get_models import get_model_names
+from ml_peg.models.models import current_models
+
+# Get all models
+MODELS = get_model_names(current_models)
+BENCHMARK_NAME = "Ice"
+DOCS_URL = (
+ "https://ddmms.github.io/ml-peg/user_guide/benchmarks/aqueous_solutions/ice.html"
+)
+DATA_PATH = APP_ROOT / "data" / "aqueous_solutions" / "ice"
+METRICS = ["rdf_score", "vdos_score", "vacf_score"]
+
+
+def render_subplot_component(click_data: dict) -> html.Div | None:
+ """
+ Render comparison plot for clicked bar.
+
+ Parameters
+ ----------
+ click_data
+ Click data from bar chart containing data.
+
+ Returns
+ -------
+ html.Div | None
+ Component containing comparison plot.
+ """
+ if not click_data or "points" not in click_data:
+ return html.Div("Click on a bar to see comparison.")
+
+ point = click_data["points"][0]
+ if "customdata" not in point or len(point["customdata"]) < 2:
+ return html.Div(f"No data available: {point.keys()}")
+
+ rdf_data = point["customdata"][1] # Get RDF data from customdata
+ pair_name = point["customdata"][0] # Get pair name
+
+ # Create matplotlib figure
+ fig, axes = plt.subplots(1, 2, figsize=(12, 4))
+ ax1, ax2 = axes
+
+ # Load data
+ x_values = rdf_data["x_values"]
+ ref_values = rdf_data["ref"]
+ pred_values = rdf_data["pred"]
+ error = rdf_data["error"]
+ xlabel = rdf_data["xlabel"]
+ ylabel = rdf_data["ylabel"]
+
+ # Plot Reference and Predicted RDFs
+ ax1.plot(x_values, ref_values, "b-", label="Reference", linewidth=2)
+ ax1.plot(x_values, pred_values, "r--", label="Predicted", linewidth=2)
+ ax1.set_xlabel(xlabel)
+ ax1.set_ylabel(ylabel)
+ ax1.set_title(f"Comparison: {pair_name}")
+ ax1.legend()
+ ax1.grid(True, alpha=0.3)
+
+ # Plot Error
+ ax2.plot(x_values, error, "k-", label="Error", linewidth=2)
+ ax2.set_xlabel(xlabel)
+ ax2.set_ylabel(rf"${{\Delta}}${ylabel}")
+ ax2.set_title("Error")
+ ax2.legend()
+ ax2.grid(True, alpha=0.3)
+
+ # Check if xlim is provided
+ if "xlim" in rdf_data:
+ ax1.set_xlim(rdf_data["xlim"])
+ ax2.set_xlim(rdf_data["xlim"])
+
+ # Convert to base64 for display
+ buffer = BytesIO()
+ plt.tight_layout()
+ plt.savefig(buffer, format="png", dpi=150, bbox_inches="tight")
+ buffer.seek(0)
+ image_base64 = base64.b64encode(buffer.read()).decode()
+ plt.close()
+
+ return html.Div(
+ [
+ html.H4(f"Comparison: {pair_name}"),
+ html.Img(
+ src=f"data:image/png;base64,{image_base64}",
+ style={"maxWidth": "100%", "border": "1px solid #ccc"},
+ ),
+ ]
+ )
+
+
+class IceApp(BaseApp):
+ """Ice benchmark app layout and callbacks."""
+
+ def register_callbacks(self) -> None:
+ """Register callbacks to app."""
+ # Assets dir will be parent directory - individual files for each system
+
+ cell_plots = {}
+ interactive_data = {}
+
+ # Load the complex interactive data from your @cell_to_bar decorator
+
+ for metric in METRICS:
+ try:
+ with open(DATA_PATH / f"{metric}_bar.json") as f:
+ interactive_data[metric] = json.load(f)
+ except FileNotFoundError:
+ interactive_data[metric] = {"models": {}, "metrics": {}}
+
+ # Extract pre-generated figures for each model-metric pair
+
+ for model_name, model_data in (
+ interactive_data[metric].get("models", {}).items()
+ ):
+ if model_name not in cell_plots:
+ cell_plots[model_name] = {}
+
+ figures = model_data.get("figures", {})
+ for metric_key, figure_data in figures.items():
+ cell_plots[model_name][metric_key] = dcc.Graph(
+ id=f"{BENCHMARK_NAME}-figure-bar-{model_name}",
+ figure=figure_data,
+ )
+
+ print("Cell plots prepared:", cell_plots.keys())
+ plot_from_table_cell(
+ table_id=self.table_id,
+ plot_id=f"{BENCHMARK_NAME}-figure-placeholder",
+ cell_to_plot=cell_plots,
+ )
+ print(cell_plots.keys())
+
+ # Add click callbacks for each model's bar charts
+ for model_name in cell_plots.keys():
+
+ @callback(
+ Output(
+ f"{BENCHMARK_NAME}-figure-plot-container-{model_name}", "children"
+ ),
+ Input(f"{BENCHMARK_NAME}-figure-bar-{model_name}", "clickData"),
+ prevent_initial_call=True,
+ )
+ def show_comparison_plot(click_data):
+ return render_subplot_component(click_data)
+
+
+def get_app() -> IceApp:
+ """
+ Get Ice benchmark app layout and callback registration.
+
+ Returns
+ -------
+ IceApp
+ Benchmark layout and callback registration.
+ """
+ extra_components = [
+ Div(id=f"{BENCHMARK_NAME}-figure-placeholder"),
+ Div(
+ id=f"{BENCHMARK_NAME}-figure-bar",
+ children="Click on a metric to see bar plot.",
+ ),
+ Div(
+ id=f"{BENCHMARK_NAME}-figure-plot-container",
+ children="Click on a bar to see comparison.",
+ ),
+ ]
+ for model_name in MODELS:
+ extra_components.append(Div(id=f"{BENCHMARK_NAME}-figure-bar-{model_name}"))
+ extra_components.append(Div(id=f"{BENCHMARK_NAME}-figure-bar-{model_name}"))
+ extra_components.append(
+ Div(id=f"{BENCHMARK_NAME}-figure-plot-container-{model_name}")
+ )
+
+ return IceApp(
+ name=BENCHMARK_NAME,
+ description="Ice score.",
+ docs_url=DOCS_URL,
+ table_path=DATA_PATH / "ice_metrics_table.json",
+ extra_components=extra_components,
+ )
diff --git a/ml_peg/app/surfaces/copper_water_interface/app_copper_water_interface.py b/ml_peg/app/surfaces/copper_water_interface/app_copper_water_interface.py
new file mode 100644
index 000000000..e07c42ba1
--- /dev/null
+++ b/ml_peg/app/surfaces/copper_water_interface/app_copper_water_interface.py
@@ -0,0 +1,214 @@
+"""Analysis of copper water interface benchmark."""
+
+from __future__ import annotations
+
+import base64
+from io import BytesIO
+
+import matplotlib
+
+matplotlib.use("Agg")
+import json
+
+from dash import Input, Output, callback, dcc, html
+from dash.html import Div
+import matplotlib.pyplot as plt
+
+from ml_peg.app import APP_ROOT
+from ml_peg.app.base_app import BaseApp
+from ml_peg.app.utils.build_callbacks import (
+ plot_from_table_cell,
+ plot_from_table_column,
+)
+from ml_peg.app.utils.load import read_plot
+from ml_peg.models.get_models import get_model_names
+from ml_peg.models.models import current_models
+
+# Get all models
+MODELS = get_model_names(current_models)
+BENCHMARK_NAME = "Copper Water Interface"
+DOCS_URL = "https://ddmms.github.io/ml-peg/user_guide/benchmarks/surfaces/copper_water_interface.html"
+DATA_PATH = APP_ROOT / "data" / "surfaces" / "copper_water_interface"
+METRICS = ["rdf_score", "vdos_score", "vacf_score"]
+
+
+def render_subplot_component(click_data: dict) -> html.Div | None:
+ """
+ Render comparison plot for clicked bar.
+
+ Parameters
+ ----------
+ click_data
+ Click data from bar chart containing data.
+
+ Returns
+ -------
+ html.Div | None
+ Component containing comparison plot.
+ """
+ if not click_data or "points" not in click_data:
+ return html.Div("Click on a bar to see comparison.")
+
+ point = click_data["points"][0]
+ if "customdata" not in point or len(point["customdata"]) < 2:
+ return html.Div(f"No data available: {point.keys()}")
+
+ rdf_data = point["customdata"][1] # Get RDF data from customdata
+ pair_name = point["customdata"][0] # Get pair name
+
+ # Create matplotlib figure
+ fig, axes = plt.subplots(1, 2, figsize=(12, 4))
+ ax1, ax2 = axes
+
+ # Load data
+ x_values = rdf_data["x_values"]
+ ref_values = rdf_data["ref"]
+ pred_values = rdf_data["pred"]
+ error = rdf_data["error"]
+ xlabel = rdf_data["xlabel"]
+ ylabel = rdf_data["ylabel"]
+
+ # Plot Reference and Predicted RDFs
+ ax1.plot(x_values, ref_values, "b-", label="Reference", linewidth=2)
+ ax1.plot(x_values, pred_values, "r--", label="Predicted", linewidth=2)
+ ax1.set_xlabel(xlabel)
+ ax1.set_ylabel(ylabel)
+ ax1.set_title(f"Comparison: {pair_name}")
+ ax1.legend()
+ ax1.grid(True, alpha=0.3)
+
+ # Plot Error
+ ax2.plot(x_values, error, "k-", label="Error", linewidth=2)
+ ax2.set_xlabel(xlabel)
+ ax2.set_ylabel(rf"${{\Delta}}${ylabel}")
+ ax2.set_title("Error")
+ ax2.legend()
+ ax2.grid(True, alpha=0.3)
+
+ # Check if xlim is provided
+ if "xlim" in rdf_data:
+ ax1.set_xlim(rdf_data["xlim"])
+ ax2.set_xlim(rdf_data["xlim"])
+
+ # Convert to base64 for display
+ buffer = BytesIO()
+ plt.tight_layout()
+ plt.savefig(buffer, format="png", dpi=150, bbox_inches="tight")
+ buffer.seek(0)
+ image_base64 = base64.b64encode(buffer.read()).decode()
+ plt.close()
+
+ return html.Div(
+ [
+ html.H4(f"Comparison: {pair_name}"),
+ html.Img(
+ src=f"data:image/png;base64,{image_base64}",
+ style={"maxWidth": "100%", "border": "1px solid #ccc"},
+ ),
+ ]
+ )
+
+
+class CopperWaterInterfaceApp(BaseApp):
+ """Copper Water Interface benchmark app layout and callbacks."""
+
+ def register_callbacks(self) -> None:
+ """Register callbacks to app."""
+ # Assets dir will be parent directory - individual files for each system
+
+ cell_plots = {}
+ interactive_data = {}
+
+ # Load the complex interactive data from your @cell_to_bar decorator
+
+ for metric in METRICS:
+ try:
+ with open(DATA_PATH / f"{metric}_bar.json") as f:
+ interactive_data[metric] = json.load(f)
+ except FileNotFoundError:
+ interactive_data[metric] = {"models": {}, "metrics": {}}
+
+ # Extract pre-generated figures for each model-metric pair
+
+ for model_name, model_data in (
+ interactive_data[metric].get("models", {}).items()
+ ):
+ if model_name not in cell_plots:
+ cell_plots[model_name] = {}
+
+ figures = model_data.get("figures", {})
+ for metric_key, figure_data in figures.items():
+ cell_plots[model_name][metric_key] = dcc.Graph(
+ id=f"{BENCHMARK_NAME}-figure-bar-{model_name}",
+ figure=figure_data,
+ )
+
+ print("Cell plots prepared:", cell_plots.keys())
+ plot_from_table_cell(
+ table_id=self.table_id,
+ plot_id=f"{BENCHMARK_NAME}-figure-placeholder",
+ cell_to_plot=cell_plots,
+ )
+ print(cell_plots.keys())
+
+ # Add click callbacks for each model's bar charts
+ for model_name in cell_plots.keys():
+
+ @callback(
+ Output(
+ f"{BENCHMARK_NAME}-figure-plot-container-{model_name}", "children"
+ ),
+ Input(f"{BENCHMARK_NAME}-figure-bar-{model_name}", "clickData"),
+ prevent_initial_call=True,
+ )
+ def show_comparison_plot(click_data):
+ return render_subplot_component(click_data)
+
+ # DIPOLE HISTOGRAM CALLBACK
+ dipole_hist = read_plot(
+ DATA_PATH / "figure_hist_dipoles.json",
+ id=f"{BENCHMARK_NAME}-figure-hist-dipoles",
+ )
+
+ plot_from_table_column(
+ table_id=self.table_id,
+ plot_id=f"{BENCHMARK_NAME}-figure-placeholder-dipole",
+ column_to_plot={"stdev_dipole_z_deviation": dipole_hist},
+ )
+
+
+def get_app() -> CopperWaterInterfaceApp:
+ """
+ Get Copper Water Interface benchmark app layout and callback registration.
+
+ Returns
+ -------
+ CopperWaterInterfaceApp
+ Benchmark layout and callback registration.
+ """
+ extra_components = [
+ Div(id=f"{BENCHMARK_NAME}-figure-placeholder"),
+ Div(id=f"{BENCHMARK_NAME}-figure-placeholder-dipole"),
+ Div(
+ id=f"{BENCHMARK_NAME}-figure-bar",
+ children="Click on a metric to see bar plot.",
+ ),
+ Div(
+ id=f"{BENCHMARK_NAME}-figure-plot-container",
+ children="Click on a bar to see comparison.",
+ ),
+ ]
+ for model_name in MODELS:
+ extra_components.append(Div(id=f"{BENCHMARK_NAME}-figure-bar-{model_name}"))
+ extra_components.append(Div(id=f"{BENCHMARK_NAME}-figure-bar-{model_name}"))
+ extra_components.append(
+ Div(id=f"{BENCHMARK_NAME}-figure-plot-container-{model_name}")
+ )
+
+ return CopperWaterInterfaceApp(
+ name=BENCHMARK_NAME,
+ description="Copper Water Interface score.",
+ docs_url=DOCS_URL,
+ table_path=DATA_PATH / "copper_water_interface_metrics_table.json",
+ extra_components=extra_components,
+ )
diff --git a/ml_peg/calcs/aqueous_solutions/bulk_water/calc_water.py b/ml_peg/calcs/aqueous_solutions/bulk_water/calc_water.py
new file mode 100644
index 000000000..ce81ef921
--- /dev/null
+++ b/ml_peg/calcs/aqueous_solutions/bulk_water/calc_water.py
@@ -0,0 +1,171 @@
+"""Run calculations for bulk benchmark."""
+
+from __future__ import annotations
+
+from datetime import date
+from pathlib import Path
+import time
+from typing import Any
+
+from ase import Atoms, units
+from ase.calculators.calculator import Calculator
+from ase.io import read, write
+from ase.md.langevin import Langevin
+from ase.md.velocitydistribution import MaxwellBoltzmannDistribution
+import pytest
+
+from ml_peg.calcs.utils.utils import download_s3_data
+from ml_peg.models.get_models import load_models
+from ml_peg.models.models import current_models
+
+MODELS = load_models(current_models)
+
+# Local directory to store output data
+OUT_PATH = Path(__file__).parent / "outputs"
+
+
+def run_md_water(
+ start_config: Atoms,
+ calc: Calculator,
+ write_dir: Path,
+ teqb: int = 25000,
+ trun: int = 300000,
+ th_dt: int = 1,
+ md_dt: int = 1,
+ timestep: float = 1,
+ temperature: int = 330,
+ friction: float = 0.05,
+) -> None:
+ """
+ Run MD to study bulk water.
+
+ Parameters
+ ----------
+ start_config : ase.Atoms
+ Initial Atoms structure.
+ calc : ase.calculators.calculator.Calculator
+ Calculator to use to evaluate structure energy.
+ write_dir : pathlib.Path
+ Directory to write output files to.
+ teqb : int, optional
+ Total number of MD steps for equilibration run. Default is 5000.
+ trun : int, optional
+ Total number of MD steps to run. Default is 300000.
+ th_dt : int, optional
+ Logfile output interval in number of MD steps (md.thermo). Default is 1.
+ md_dt : int, optional
+ Coordinate output interval in number of MD steps (md.xyz). Default is 1.
+ timestep : float, optional
+ MD timestep in fs. Default is 1.
+ temperature : int, optional
+ MD temperature in K. Default is 330.
+ friction : float, optional
+ Friction coefficient for Langevin thermostat. Default is 0.05.
+ """
+ MaxwellBoltzmannDistribution(start_config, temperature_K=temperature)
+
+ start_config.calc = calc
+ start_config.pbc = [True, True, True]
+
+ # Open coordinates file and thermo file
+ thermo_traj = open(write_dir / "md.thermo", "w")
+ coord_traj_name = write_dir / "md-pos.xyz"
+ velc_traj_name = write_dir / "md-velc.xyz"
+ # Remove any existing .xyz files to avoid appending to old data
+ if coord_traj_name.exists():
+ coord_traj_name.unlink()
+ if velc_traj_name.exists():
+ velc_traj_name.unlink()
+
+ def print_traj(config=start_config):
+ """
+ Print trajectory information during MD.
+
+ Parameters
+ ----------
+ config : ase.Atoms, optional
+ Atoms configuration to print. Default is start_config.
+ """
+ calc_time = (dyn.get_time()) / units.fs
+ calc_temp = config.get_temperature()
+ calc_epot = config.get_potential_energy()
+ calc_walltime = time.time() - glob_start_time
+
+ if dyn.nsteps % th_dt == 0:
+ thermo_traj.write(
+ ("%17.2f" + " %17.6f" * 3 + "\n")
+ % (calc_time, calc_temp, calc_epot, calc_walltime)
+ )
+ thermo_traj.flush()
+ if dyn.nsteps % md_dt == 0:
+ coords_write = Atoms(
+ numbers=config.numbers,
+ positions=config.get_positions(),
+ cell=config.cell,
+ pbc=config.pbc,
+ )
+ write(coord_traj_name, coords_write, append=True)
+ velocities_write = Atoms(
+ numbers=config.numbers,
+ positions=config.get_velocities(),
+ cell=config.cell,
+ pbc=config.pbc,
+ )
+ write(velc_traj_name, velocities_write, append=True)
+
+ thermo_traj.write(
+ "# ASE Dynamics. Date: " + date.today().strftime("%d %b %Y") + "\n"
+ )
+ thermo_traj.write(
+ "# Time(fs) Temperature(K) Energy(eV) Walltime(s) \n"
+ )
+
+ open(coord_traj_name, "w").close()
+ glob_start_time = time.time()
+
+ # RUN MD WITH LANGEVIN THERMOSTAT
+ dyn = Langevin(
+ start_config,
+ timestep * units.fs,
+ temperature_K=temperature,
+ friction=friction,
+ )
+ dyn.run(teqb) # Equilibration run
+ dyn.attach(print_traj)
+ print_traj(start_config)
+ dyn.run(trun)
+
+ thermo_traj.close()
+
+
+@pytest.mark.parametrize("mlip", MODELS.items())
+def test_bulk_water(mlip: tuple[str, Any]) -> None:
+ """
+ Run Bulk Water test.
+
+ Parameters
+ ----------
+ mlip
+ Name of model use and model to get calculator.
+ """
+ # Setup calculator with d3 correction
+ model_name, model = mlip
+ calc = model.get_calculator()
+ calc = model.add_d3_calculator(calc)
+
+ # Get copper water benchmark data
+ data_dir = (
+ download_s3_data(
+ filename="bulk_water.zip",
+ key="inputs/aqueous-solutions/bulk_water/bulk_water.zip",
+ )
+ / "bulk_water"
+ )
+
+ # Load initial structure
+ start_config = read(data_dir / "init.xyz")
+ write_dir = OUT_PATH / model_name
+ write_dir.mkdir(parents=True, exist_ok=True)
+
+ # Run MD
+ run_md_water(start_config, calc, write_dir=write_dir)
diff --git a/ml_peg/calcs/aqueous_solutions/ice/calc_ice.py b/ml_peg/calcs/aqueous_solutions/ice/calc_ice.py
new file mode 100644
index 000000000..e86bf610c
--- /dev/null
+++ b/ml_peg/calcs/aqueous_solutions/ice/calc_ice.py
@@ -0,0 +1,171 @@
+"""Run calculations for ice benchmark."""
+
+from __future__ import annotations
+
+from datetime import date
+from pathlib import Path
+import time
+from typing import Any
+
+from ase import Atoms, units
+from ase.calculators.calculator import Calculator
+from ase.io import read, write
+from ase.md.langevin import Langevin
+from ase.md.velocitydistribution import MaxwellBoltzmannDistribution
+import pytest
+
+from ml_peg.calcs.utils.utils import download_s3_data
+from ml_peg.models.get_models import load_models
+from ml_peg.models.models import current_models
+
+MODELS = load_models(current_models)
+
+# Local directory to store output data
+OUT_PATH = Path(__file__).parent / "outputs"
+
+
+def run_md_ice(
+ start_config: Atoms,
+ calc: Calculator,
+ write_dir: Path,
+ teqb: int = 25000,
+ trun: int = 300000,
+ th_dt: int = 1,
+ md_dt: int = 1,
+ timestep: float = 1,
+ temperature: int = 250,
+ friction: float = 0.05,
+) -> None:
+ """
+ Run MD to study ice.
+
+ Parameters
+ ----------
+ start_config : ase.Atoms
+ Initial Atoms structure.
+ calc : ase.calculators.calculator.Calculator
+ Calculator to use to evaluate structure energy.
+ write_dir : pathlib.Path
+ Directory to write output files to.
+ teqb : int, optional
+ Total number of MD steps for equilibration run. Default is 5000.
+ trun : int, optional
+ Total number of MD steps to run. Default is 300000.
+ th_dt : int, optional
+ Logfile output interval in number of MD steps (md.thermo). Default is 1.
+ md_dt : int, optional
+ Coordinate output interval in number of MD steps (md.xyz). Default is 1.
+ timestep : float, optional
+ MD timestep in fs. Default is 1.
+ temperature : int, optional
+ MD temperature in K. Default is 250.
+ friction : float, optional
+ Friction coefficient for Langevin thermostat. Default is 0.05.
+ """
+ MaxwellBoltzmannDistribution(start_config, temperature_K=temperature)
+
+ start_config.calc = calc
+ start_config.pbc = [True, True, True]
+
+ # Open coordinates file and thermo file
+ thermo_traj = open(write_dir / "md.thermo", "w")
+ coord_traj_name = write_dir / "md-pos.xyz"
+ velc_traj_name = write_dir / "md-velc.xyz"
+ # Remove any existing .xyz files to avoid appending to old data
+ if coord_traj_name.exists():
+ coord_traj_name.unlink()
+ if velc_traj_name.exists():
+ velc_traj_name.unlink()
+
+ def print_traj(config=start_config):
+ """
+ Print trajectory information during MD.
+
+ Parameters
+ ----------
+ config : ase.Atoms, optional
+ Atoms configuration to print. Default is start_config.
+ """
+ calc_time = (dyn.get_time()) / units.fs
+ calc_temp = config.get_temperature()
+ calc_epot = config.get_potential_energy()
+ calc_walltime = time.time() - glob_start_time
+
+ if dyn.nsteps % th_dt == 0:
+ thermo_traj.write(
+ ("%17.2f" + " %17.6f" * 3 + "\n")
+ % (calc_time, calc_temp, calc_epot, calc_walltime)
+ )
+ thermo_traj.flush()
+ if dyn.nsteps % md_dt == 0:
+ coords_write = Atoms(
+ numbers=config.numbers,
+ positions=config.get_positions(),
+ cell=config.cell,
+ pbc=config.pbc,
+ )
+ write(coord_traj_name, coords_write, append=True)
+ velocities_write = Atoms(
+ numbers=config.numbers,
+ positions=config.get_velocities(),
+ cell=config.cell,
+ pbc=config.pbc,
+ )
+ write(velc_traj_name, velocities_write, append=True)
+
+ thermo_traj.write(
+ "# ASE Dynamics. Date: " + date.today().strftime("%d %b %Y") + "\n"
+ )
+ thermo_traj.write(
+ "# Time(fs) Temperature(K) Energy(eV) Walltime(s) \n"
+ )
+
+ open(coord_traj_name, "w").close()
+ glob_start_time = time.time()
+
+ # RUN MD WITH LANGEVIN THERMOSTAT
+ dyn = Langevin(
+ start_config,
+ timestep * units.fs,
+ temperature_K=temperature,
+ friction=friction,
+ )
+ dyn.run(teqb) # Equilibration run
+ dyn.attach(print_traj)
+ print_traj(start_config)
+ dyn.run(trun)
+
+ thermo_traj.close()
+
+
+@pytest.mark.parametrize("mlip", MODELS.items())
+def test_ice(mlip: tuple[str, Any]) -> None:
+ """
+ Run Ice test.
+
+ Parameters
+ ----------
+ mlip
+ Name of model use and model to get calculator.
+ """
+ # Setup calculator with d3 correction
+ model_name, model = mlip
+ calc = model.get_calculator()
+ calc = model.add_d3_calculator(calc)
+
+ # Get copper water benchmark data
+ data_dir = (
+ download_s3_data(
+ filename="ice.zip",
+ key="inputs/aqueous-solutions/ice/ice.zip",
+ )
+ / "ice"
+ )
+
+ # Load initial structure
+ start_config = read(data_dir / "init.xyz")
+ write_dir = OUT_PATH / model_name
+ write_dir.mkdir(parents=True, exist_ok=True)
+
+ # Run MD
+ run_md_ice(start_config, calc, write_dir=write_dir)
diff --git a/ml_peg/calcs/surfaces/copper_water_interface/calc_copper_water_interface.py b/ml_peg/calcs/surfaces/copper_water_interface/calc_copper_water_interface.py
new file mode 100644
index 000000000..561224ae1
--- /dev/null
+++ b/ml_peg/calcs/surfaces/copper_water_interface/calc_copper_water_interface.py
@@ -0,0 +1,233 @@
+"""Run calculations for copper water interface benchmark."""
+
+from __future__ import annotations
+
+from datetime import date
+from pathlib import Path
+import time
+from typing import Any
+
+from ase import Atoms, units
+from ase.calculators.calculator import Calculator
+from ase.constraints import FixAtoms
+from ase.io import read, write
+from ase.md.langevin import Langevin
+from ase.md.velocitydistribution import MaxwellBoltzmannDistribution
+from matscipy.neighbours import neighbour_list
+import numpy as np
+import pytest
+
+from ml_peg.calcs.utils.utils import download_s3_data
+from ml_peg.models.get_models import load_models
+from ml_peg.models.models import current_models
+
+MODELS = load_models(current_models)
+
+# Local directory to store output data
+OUT_PATH = Path(__file__).parent / "outputs"
+
+
+def get_net_dipole_moment_water(
+ atoms, o_indexes, q_charge=0.8476, cutoff=1.2
+) -> np.ndarray:
+ """
+ Calculate net dipole moment of water molecules.
+
+ Computes the net dipole moment of an Atoms object with water molecules by
+ summing over the dipole moments of each water molecule.
+
+ Parameters
+ ----------
+ atoms : ase.Atoms
+ ASE Atoms object.
+ o_indexes : list
+ List of indexes of oxygen atoms in the Atoms object.
+ q_charge : float, optional
+ Twice the partial charge on hydrogen atoms in water. Default is 0.8476.
+ cutoff : float, optional
+ Cutoff distance to identify bonded atoms. Default is 1.2.
+
+ Returns
+ -------
+ np.ndarray
+ Net dipole moment vector of the water molecules.
+ """
+ i_index, bond_lengths = neighbour_list(
+ quantities="iD",
+ atoms=atoms,
+ cutoff={("O", "H"): cutoff},
+ )
+ # Filter bonds to only those involving oxygen atoms
+ mask = np.isin(i_index, o_indexes)
+ o_bond_lengths = bond_lengths[mask]
+
+ return (q_charge / 2) * np.sum(o_bond_lengths, axis=0)
+
+
+def run_md(
+ start_config: Atoms,
+ calc: Calculator,
+ write_dir: Path,
+ teqb: int = 5000,
+ trun: int = 30000,
+ th_dt: int = 1,
+ md_dt: int = 1,
+ timestep: float = 1,
+ temperature: int = 330,
+ friction: float = 0.05,
+) -> None:
+ """
+ Run MD to study copper water interface.
+
+ Parameters
+ ----------
+ start_config : ase.Atoms
+ Initial Atoms structure.
+ calc : ase.calculators.calculator.Calculator
+ Calculator to use to evaluate structure energy.
+ write_dir : pathlib.Path
+ Directory to write output files to.
+ teqb : int, optional
+ Total number of MD steps for equilibration run. Default is 5000.
+ trun : int, optional
+ Total number of MD steps to run. Default is 105.
+ th_dt : int, optional
+ Logfile output interval in number of MD steps (md.thermo). Default is 1.
+ md_dt : int, optional
+ Coordinate output interval in number of MD steps (md.xyz). Default is 1.
+ timestep : float, optional
+ MD timestep in fs. Default is 1.
+ temperature : int, optional
+ MD temperature in K. Default is 330.
+ friction : float, optional
+ Friction coefficient for Langevin thermostat. Default is 0.05.
+ """
+ MaxwellBoltzmannDistribution(start_config, temperature_K=temperature)
+ o_indexes = [atom.index for atom in start_config if atom.symbol == "O"]
+ area = (
+ start_config.get_volume() / start_config.cell[2, 2]
+ ) # xy area of simulation cell
+
+ # Set deuterium mass for H atoms
+ mass_array = start_config.get_masses()
+ for i, atom in enumerate(start_config):
+ if atom.symbol == "H":
+ mass_array[i] = 2.0
+ start_config.set_masses(mass_array)
+
+ start_config.calc = calc
+ start_config.pbc = [True, True, True]
+
+ # Fix Bottom Layers of slab
+ if "fix_indices" in start_config.info:
+ c = FixAtoms(start_config.info["fix_indices"])
+ start_config.set_constraint(c)
+ else:
+ raise ValueError("Structure missing 'fix_indices' in info dict")
+
+ # Open coordinates file and thermo file
+ thermo_traj = open(write_dir / "md.thermo", "w")
+ coord_traj_name = write_dir / "md-pos.xyz"
+ velc_traj_name = write_dir / "md-velc.xyz"
+ # Remove any existing .xyz files to avoid appending to old data
+ if coord_traj_name.exists():
+ coord_traj_name.unlink()
+ if velc_traj_name.exists():
+ velc_traj_name.unlink()
+
+ def print_traj(config=start_config):
+ """
+ Print trajectory information during MD.
+
+ Parameters
+ ----------
+ config : ase.Atoms, optional
+ Atoms configuration to print. Default is start_config.
+ """
+ calc_time = (dyn.get_time()) / units.fs
+ calc_temp = config.get_temperature()
+ calc_epot = config.get_potential_energy()
+ calc_walltime = time.time() - glob_start_time
+ dipole_z = get_net_dipole_moment_water(config, o_indexes)[2]
+ dipole_z_per_area = dipole_z / area
+
+ if dyn.nsteps % th_dt == 0:
+ thermo_traj.write(
+ ("%17.2f" + " %17.6f" * 4 + "\n")
+ % (calc_time, calc_temp, calc_epot, calc_walltime, dipole_z_per_area)
+ )
+ thermo_traj.flush()
+ if dyn.nsteps % md_dt == 0:
+ coords_write = Atoms(
+ numbers=config.numbers,
+ positions=config.get_positions(),
+ cell=config.cell,
+ pbc=config.pbc,
+ )
+ coords_write.info["dipole_z"] = dipole_z_per_area
+ write(coord_traj_name, coords_write, append=True)
+ velocities_write = Atoms(
+ numbers=config.numbers,
+ positions=config.get_velocities(),
+ cell=config.cell,
+ pbc=config.pbc,
+ )
+ write(velc_traj_name, velocities_write, append=True)
+
+ thermo_traj.write(
+ "# ASE Dynamics. Date: " + date.today().strftime("%d %b %Y") + "\n"
+ )
+ thermo_traj.write(
+ "# Time(fs) Temperature(K) Energy(eV) "
+ "Walltime(s) Dipole_z_per_area(e/A)\n"
+ )
+
+ open(coord_traj_name, "w").close()
+ glob_start_time = time.time()
+
+ # RUN MD WITH LANGEVIN THERMOSTAT
+ dyn = Langevin(
+ start_config,
+ timestep * units.fs,
+ temperature_K=temperature,
+ friction=friction,
+ )
+ dyn.run(teqb) # Equilibration run
+ dyn.attach(print_traj)
+ print_traj(start_config)
+ dyn.run(trun)
+
+ thermo_traj.close()
+
+
+@pytest.mark.parametrize("mlip", MODELS.items())
+def test_copper_water_interface(mlip: tuple[str, Any]) -> None:
+ """
+ Run Copper-Water Interface test.
+
+ Parameters
+ ----------
+ mlip
+ Name of model use and model to get calculator.
+ """
+ # Setup calculator with d3 correction
+ model_name, model = mlip
+ calc = model.get_calculator()
+ calc = model.add_d3_calculator(calc)
+
+ # Get copper water benchmark data
+ data_dir = (
+ download_s3_data(
+ filename="copper_water_interface.zip",
+ key="inputs/surfaces/copper_water_interface/copper_water_interface.zip",
+ )
+ / "copper_water_interface"
+ )
+
+ # Load initial structure
+ start_config = read(data_dir / "init.xyz")
+ write_dir = OUT_PATH / model_name
+ write_dir.mkdir(parents=True, exist_ok=True)
+
+ # Run MD
+ run_md(start_config, calc, write_dir=write_dir)
diff --git a/uv.lock b/uv.lock
index f828ab629..558e766fb 100644
--- a/uv.lock
+++ b/uv.lock
@@ -19,7 +19,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
@@ -39,7 +40,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -49,13 +51,16 @@ resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -70,7 +75,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -79,13 +85,16 @@ resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -104,7 +113,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -120,7 +130,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
conflicts = [[
@@ -573,7 +584,8 @@ version = "0.0.21"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32'",
]
@@ -1453,28 +1465,35 @@ version = "1.3.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -1584,8 +1603,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -1608,8 +1629,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -2366,21 +2389,40 @@ name = "e3nn"
version = "0.4.4"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
- "python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version >= '3.14' and sys_platform == 'win32'",
- "python_full_version == '3.13.*' and sys_platform == 'win32'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
- "(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32')",
- "(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
- "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
+ "python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.13.*' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
{ name = "opt-einsum-fx" },
@@ -2416,7 +2458,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32'",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32'",
]
@@ -2438,28 +2481,35 @@ version = "0.85.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -2520,8 +2570,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -2544,8 +2596,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -2603,6 +2657,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/35/a8/365059bbcd4572cbc41de17fd5b682be5868b218c3c5479071865cab9078/entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f", size = 5294, upload-time = "2022-02-02T21:30:26.024Z" },
]
+[[package]]
+name = "et-xmlfile"
+version = "2.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" },
+]
+
[[package]]
name = "eventlet"
version = "0.40.4"
@@ -3279,28 +3342,35 @@ version = "1.0.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -3357,8 +3427,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -3381,8 +3453,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -3771,28 +3845,35 @@ version = "8.38.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -3856,8 +3937,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -3880,8 +3963,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -4413,7 +4498,8 @@ version = "3.12.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
dependencies = [
@@ -4438,8 +4524,10 @@ source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
]
@@ -4910,28 +4998,35 @@ version = "0.9.3"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -4994,8 +5089,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -5018,8 +5115,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -5166,11 +5265,14 @@ resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
dependencies = [
@@ -5217,7 +5319,8 @@ resolution-markers = [
"python_full_version == '3.11.*' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
dependencies = [
@@ -5328,28 +5431,35 @@ version = "2.9.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -5429,8 +5539,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -5453,8 +5565,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -5539,11 +5653,14 @@ resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
dependencies = [
@@ -5583,7 +5700,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
@@ -5603,7 +5721,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -5625,7 +5744,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -5650,7 +5770,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -5666,7 +5787,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -5808,11 +5930,14 @@ resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
dependencies = [
@@ -5856,7 +5981,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
@@ -5876,7 +6002,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -5898,7 +6025,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -5923,7 +6051,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -5939,7 +6068,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -5998,6 +6128,7 @@ dependencies = [
{ name = "mdanalysis", version = "2.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-uma') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-uma')" },
{ name = "mdanalysis", version = "2.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-uma') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-uma')" },
{ name = "mlipx" },
+ { name = "openpyxl" },
{ name = "scikit-learn", version = "1.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-uma') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-uma')" },
{ name = "scikit-learn", version = "1.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-uma') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim') or (extra == 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-uma')" },
{ name = "tqdm" },
@@ -6078,6 +6209,7 @@ requires-dist = [
{ name = "mattersim", marker = "extra == 'mattersim'", specifier = "==1.2.0" },
{ name = "mdanalysis" },
{ name = "mlipx", specifier = ">=0.1.5,<0.2" },
+ { name = "openpyxl" },
{ name = "orb-models", marker = "python_full_version < '3.13' and sys_platform != 'win32' and extra == 'orb'", specifier = "==0.5.5" },
{ name = "pet-mad", marker = "sys_platform != 'win32' and extra == 'pet-mad'", specifier = "==1.4.4" },
{ name = "scikit-learn", specifier = ">=1.7.1" },
@@ -6195,28 +6327,35 @@ version = "0.45.13"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -6278,8 +6417,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -6302,8 +6443,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -6730,28 +6873,35 @@ version = "3.4.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368, upload-time = "2024-10-21T12:39:38.695Z" }
@@ -6802,8 +6952,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -6826,8 +6978,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -6943,11 +7097,14 @@ resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" }
@@ -7000,7 +7157,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
@@ -7020,7 +7178,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -7042,7 +7201,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -7067,7 +7227,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -7083,7 +7244,8 @@ resolution-markers = [
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" }
@@ -7337,6 +7499,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" },
]
+[[package]]
+name = "openpyxl"
+version = "3.1.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "et-xmlfile" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" },
+]
+
[[package]]
name = "opt-einsum"
version = "3.4.0"
@@ -7946,28 +8120,35 @@ version = "0.24.4"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -8024,8 +8205,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -8048,8 +8231,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -8309,11 +8494,14 @@ resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
sdist = { url = "https://files.pythonhosted.org/packages/df/01/34c8d2b6354906d728703cb9d546a0e534de479e25f1b581e4094c4a85cc/protobuf-4.25.8.tar.gz", hash = "sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd", size = 380920, upload-time = "2025-05-28T14:22:25.153Z" }
@@ -8348,7 +8536,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
@@ -8368,7 +8557,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -8394,7 +8584,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
@@ -8762,28 +8953,35 @@ version = "1.18.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -8872,8 +9070,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -8896,8 +9096,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -9993,28 +10195,35 @@ version = "1.7.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -10101,8 +10310,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -10125,8 +10336,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -10213,28 +10426,35 @@ version = "1.15.3"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra == 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra == 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32' and extra != 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
]
dependencies = [
@@ -10333,8 +10553,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra == 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -10357,8 +10579,10 @@ resolution-markers = [
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version >= '3.14' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"python_full_version == '3.13.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.12.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
- "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma'",
"(python_full_version >= '3.14' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version >= '3.14' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.13.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.13.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32' and extra == 'extra-6-ml-peg-grace' and extra != 'extra-6-ml-peg-mace' and extra != 'extra-6-ml-peg-mattersim' and extra != 'extra-6-ml-peg-uma')",
@@ -11100,11 +11324,14 @@ resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
- "python_full_version == '3.12.*' and sys_platform == 'win32'",
- "python_full_version == '3.11.*' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.12.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version == '3.11.*' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32')",
"(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32')",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32')",
]
dependencies = [
@@ -11144,7 +11371,8 @@ resolution-markers = [
"python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'win32'",
"python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'win32'",
- "python_full_version < '3.11' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'",
+ "python_full_version < '3.11' and platform_machine != 'ARM64' and sys_platform == 'win32'",
"python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux'",
"python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'win32'",
]