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 @@ +commit 7d8bfdcb3d52f89081200dcdf300788b96edc5d3 +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 1122690031 -> 0 bytes + ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/init.pdb | 618 -------------------------------------------- + ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/rdf_reference.pkl | Bin 14970 -> 0 bytes + .../calcs/surfaces/copper_water_interface/data/copper_water_interface/ref_dipole_data.npy | Bin 251520 -> 0 bytes + .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vacf_reference.pkl | Bin 1039681 -> 0 bytes + .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vdos_reference.pkl | Bin 96450 -> 0 bytes + ml_peg/calcs/surfaces/copper_water_interface/data/old-cwi.zip | Bin 637519881 -> 0 bytes + 7 files changed, 618 deletions(-) + +commit b410110af654a7165bfdd67e20e9494c2cec410e +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 0 -> 1122690031 bytes + ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/init.pdb | 618 ++++++++++++++++++++++++++++++++++++++++++++ + ml_peg/calcs/surfaces/copper_water_interface/data/copper_water_interface/rdf_reference.pkl | Bin 0 -> 14970 bytes + .../calcs/surfaces/copper_water_interface/data/copper_water_interface/ref_dipole_data.npy | Bin 0 -> 251520 bytes + .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vacf_reference.pkl | Bin 0 -> 1039681 bytes + .../calcs/surfaces/copper_water_interface/data/copper_water_interface/vdos_reference.pkl | Bin 0 -> 96450 bytes + ml_peg/calcs/surfaces/copper_water_interface/data/old-cwi.zip | Bin 0 -> 637519881 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'", ]