Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

clease

Package Overview
Dependencies
Maintainers
2
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

clease - npm Package Compare versions

Comparing version
0.11.6
to
1.0.0
+2
-2
clease.egg-info/PKG-INFO
Metadata-Version: 2.1
Name: clease
Version: 0.11.6
Version: 1.0.0
Summary: CLuster Expansion in Atomistic Simulation Environment

@@ -12,3 +12,3 @@ Home-page: https://gitlab.com/computationalmaterials/clease/

Keywords: Cluster Expansion,Monte Carlo,Computational materials,Materials research
Classifier: Development Status :: 4 - Beta
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)

@@ -15,0 +15,0 @@ Classifier: Programming Language :: Python :: 3.7

@@ -16,21 +16,21 @@ ase<3.23,>=3.20

[all]
clease-gui
clang-format>=14.0.3
ipython
mock
pytest
pyclean>=2.0.0
pytest-mock
pylint
black>=22.1.0
sphinx
pre-commit
pytest-cov
cython
clease-gui
clang-format>=14.0.3
tox>=3.24.0
pip
black>=22.1.0
tox>=3.24.0
pytest-benchmark[histogram]>=3.4.1
pylint
twine
mock
sphinx_rtd_theme
build
twine
pytest
sphinx
pytest-mock
pyclean>=2.0.0
pytest-benchmark[histogram]>=3.4.1
pytest-cov

@@ -37,0 +37,0 @@ [dev]

@@ -11,3 +11,2 @@ LICENSE.md

clease/cluster_coverage.py
clease/concentration.py
clease/convexhull.py

@@ -26,7 +25,4 @@ clease/corr_func.py

clease/mp_logger.py
clease/new_struct.py
clease/plot_post_process.py
clease/regression_old.py
clease/sparsifier.py
clease/structure_generator.py
clease/structure_mapper.py

@@ -33,0 +29,0 @@ clease/svd.py

# pylint: disable=undefined-variable
import logging
from deprecated import deprecated
from .version import *

@@ -5,0 +4,0 @@

@@ -1,1 +0,1 @@

0.11.6
1.0.0

@@ -314,3 +314,3 @@ from typing import Sequence, Set, Dict, List, Iterator, Tuple

)
logger.info("Trivial supercell with repetition: (%d, %d, %d)", nx, ny, nz)
logger.debug("Trivial supercell with repetition: (%d, %d, %d)", nx, ny, nz)
else:

@@ -323,3 +323,3 @@ # Choose the generalized pathway.

)
logger.info("Non-trivial supercell, will wrap using cartesian coordinates")
logger.debug("Non-trivial supercell, will wrap using cartesian coordinates")

@@ -326,0 +326,0 @@ lut = self.create_four_vector_lut(template)

@@ -8,4 +8,5 @@ """Module that fits ECIs to energy data."""

import multiprocessing as mp
from typing import Optional, Dict, List
from typing import Dict, List
from deprecated import deprecated
import numpy as np

@@ -23,3 +24,3 @@ from ase.db import connect

__all__ = ("Evaluate",)
__all__ = ("Evaluate", "supports_alpha_cv")

@@ -116,3 +117,2 @@ # Initialize a module-wide logger

self.scheme = None
self.scheme_string = None
self.nsplits = nsplits

@@ -159,3 +159,2 @@ self.num_repetitions = num_repetitions

self.eci = None
self._alpha = None
self.e_pred_loo = None

@@ -173,2 +172,17 @@ self.parallel = parallel

@property
def scoring_scheme(self) -> str:
return self._scoring_scheme
@scoring_scheme.setter
def scoring_scheme(self, value: str) -> None:
if not isinstance(value, str):
raise TypeError(f"Scoring scheme should be string, got {value!r}")
value = value.lower()
allowed_schemas = {"loocv", "loocv_fast", "k-fold"}
if value not in allowed_schemas:
schemas_s = ", ".join(sorted(allowed_schemas))
raise ValueError(f"Unknown scoring scheme: {value}. Allowed schemas: {schemas_s}")
self._scoring_scheme = value
@property
def concentrations(self):

@@ -188,3 +202,3 @@ """

allowed_fitting_schemes = ["ridge", "tikhonov", "lasso", "l1", "l2", "ols"]
allowed_fitting_schemes = ["ridge", "tikhonov", "lasso", "l1", "l2", "ols", "linear"]
if isinstance(fitting_scheme, LinearRegression):

@@ -194,3 +208,2 @@ self.scheme = fitting_scheme

fitting_scheme = fitting_scheme.lower()
self.scheme_string = fitting_scheme
if fitting_scheme not in allowed_fitting_schemes:

@@ -206,5 +219,7 @@ raise ValueError(f"Fitting scheme has to be one of {allowed_fitting_schemes}")

self.scheme = Lasso(alpha=alpha)
else:
elif fitting_scheme in ["ols", "linear"]:
# Perform ordinary least squares
self.scheme = LinearRegression()
else:
raise ValueError(f"Unknown fitting scheme: {fitting_scheme}")
else:

@@ -217,9 +232,4 @@ raise ValueError(

# If the fitting scheme is changed, the ECIs computed are no
# longer consistent with the scheme
# By setting it to None, a new calculation is performed
# when the ECIs are requested
# Also reset the "last alpha"
# Unset the ECI, so a new fit is required.
self.eci = None
self._alpha = None

@@ -281,60 +291,47 @@ N = len(self.e_dft)

"""Check whether we need to calculate the ECI values."""
return self.eci is None or self._alpha != self.scheme.alpha
return self.eci is None
def fit(self) -> None:
"""Determine the ECI for a given alpha.
"""Determine the ECI with the given regressor.
This method also saves the last value of alpha used and
the corresponding ECIs (self.eci) such that ECIs are not calculated
repeated if alpha value is unchanged.
This will always calculate a new fit.
"""
if self.fit_required():
self._do_fit()
self.eci = self.scheme.fit(self.cf_matrix, self.e_dft)
assert self.eci is not None
def _do_fit(self) -> None:
"""Fit using the current scheme, and remember the alpha"""
self.eci = self.scheme.fit(self.cf_matrix, self.e_dft)
# Remember the latest alpha
self._alpha = self.scheme.alpha
def get_eci(self, allow_fit: bool = True) -> np.ndarray:
def get_eci(self) -> np.ndarray:
"""Determine and return ECIs for a given alpha.
Raises a ValueError if no fit has been performed yet.
Args:
allow_fit (bool, optional): Is a new fit allowed to be run before returning the ECI's?
If no ECI's are present yet, and no re-fitting was allowed, then a ValueError
is raised.
Defaults to True.
Returns:
np.ndarray: A 1D array of floats with all ECI values.
"""
if allow_fit:
self.fit()
if self.eci is None:
# getting ECI's was not allowed to fit, and we havn't run a fit yet.
raise ValueError("ECI's has not been fit yet.")
raise ValueError("ECI's has not been fit yet. Call the Evaluate.fit method first.")
return self.eci
def get_eci_dict(self, allow_fit: bool = True):
def get_eci_dict(self, cutoff_tol: float = 1e-14) -> Dict[str, float]:
"""Determine cluster names and their corresponding ECI value and return
them in a dictionary format.
Args:
cutoff_tol (float, optional): Cutoff value below which the absolute ECI
value is considered to be 0. Defaults to 1e-14.
Returns:
Dict[str, float]: Dictionary with the CF names and the corresponding
ECI value.
"""
Determine cluster names and their corresponding ECI value and return
them in a dictionary format."""
self.get_eci(allow_fit=allow_fit)
eci = self.get_eci()
# sanity check
if len(self.cf_names) != len(self.eci):
if len(self.cf_names) != len(eci):
raise ValueError("lengths of cf_names and ECIs are not same")
i_nonzeros = np.nonzero(self.eci)[0]
pairs = []
for i, cname in enumerate(self.cf_names):
if i not in i_nonzeros:
continue
pairs.append((cname, self.eci[i]))
all_nonzero = np.abs(eci) > cutoff_tol
# Only keep the all non-zero values.
return {cf: val for cf, val, nonzero in zip(self.cf_names, eci, all_nonzero) if nonzero}
return dict(pairs)
def load_eci_dict(self, eci_dict: Dict[str, float]) -> None:

@@ -365,3 +362,3 @@ """Load the ECI's from a dictionary. Any ECI's which are missing

def save_eci(self, fname="eci.json"):
def save_eci(self, fname="eci.json", **kwargs):
"""

@@ -375,7 +372,10 @@ Save a dictionary of cluster names and their corresponding ECI value

json filename. If no extension if given, .json is added
kwargs:
Extra keywords are passed on to the :meth:`~get_eci_dict` method.
"""
full_fname = add_file_extension(fname, ".json")
with open(full_fname, "w") as outfile:
json.dump(self.get_eci_dict(), outfile, indent=2, separators=(",", ": "))
json.dump(self.get_eci_dict(**kwargs), outfile, indent=2, separators=(",", ": "))
@deprecated(reason="Use the clease.plot_post_process module instead.", version="0.11.7")
def plot_fit(self, interactive=False, savefig=False, fname=None, show_hull=True):

@@ -419,9 +419,6 @@ """Plot calculated (DFT) and predicted energies for a given alpha.

cv_name = "LOOCV"
if self.scoring_scheme == "loocv":
cv = self.loocv() * 1000.0
elif self.scoring_scheme == "loocv_fast":
cv = self.loocv_fast() * 1000.0
elif self.scoring_scheme == "k-fold":
cv = self.k_fold_cv() * 1000.0
cv = self.get_cv_score() * 1000.0
if self.scoring_scheme == "k-fold":
cv_name = f"{self.nsplits}-fold"
t = np.arange(rmin - 10, rmax + 10, 1)

@@ -629,18 +626,9 @@ fig = plt.figure()

if fitting_schemes is None:
if self.scheme_string is None:
raise ValueError("No fitting scheme supplied!")
if self.scheme_string in ["lasso", "l1"]:
from clease.regression import Lasso
if not supports_alpha_cv(self.scheme):
raise ValueError(f"Scheme must support scalar alpha, got {self.scheme!r}")
fitting_schemes = Lasso.get_instance_array(
alpha_min, alpha_max, num_alpha=num_alpha, scale=scale
)
elif self.scheme_string in ["ridge", "l2", "tikhonov"]:
from clease.regression import Tikhonov
fitting_schemes = self.scheme.get_instance_array(
alpha_min, alpha_max, num_alpha=num_alpha, scale=scale
)
fitting_schemes = Tikhonov.get_instance_array(
alpha_min, alpha_max, num_alpha=num_alpha, scale=scale
)
for scheme in fitting_schemes:

@@ -691,9 +679,5 @@ if not isinstance(scheme, LinearRegression):

self.set_fitting_scheme(fitting_scheme=scheme)
if self.scoring_scheme == "loocv":
cv[i] = self.loocv()
elif self.scoring_scheme == "loocv_fast":
cv[i] = self.loocv_fast()
elif self.scoring_scheme == "k-fold":
cv[i] = self.k_fold_cv()
num_eci = len(np.nonzero(self.get_eci(allow_fit=True))[0])
cv[i] = self.get_cv_score()
self.fit()
num_eci = len(np.nonzero(self.get_eci())[0])
alpha = scheme.get_scalar_parameter()

@@ -722,9 +706,5 @@ alphas.append(alpha)

self.scheme.alpha = alpha
if self.scoring_scheme == "loocv":
cv = self.loocv()
elif self.scoring_scheme == "loocv_fast":
cv = self.loocv_fast()
elif self.scoring_scheme == "k-fold":
cv = self.k_fold_cv()
num_eci = len(np.nonzero(self.get_eci(allow_fit=True))[0])
cv = self.get_cv_score()
self.fit()
num_eci = len(np.nonzero(self.get_eci())[0])
self._cv_scores.append({"alpha": alpha, "cv": cv})

@@ -740,2 +720,3 @@ logger.info(f"{alpha:.10f}\t {num_eci}\t {cv:.10f}")

@deprecated(reason="Use the alpha_CV method instead.", version="0.11.7")
def plot_CV(

@@ -840,2 +821,3 @@ self,

@deprecated(reason="Logfile is being removed.", version="0.11.7")
def _get_alphas_cv_from_file(self, logfile):

@@ -893,2 +875,3 @@ alphas = []

@deprecated(reason="Use the clease.plot_post_process module instead.", version="0.11.7")
def plot_ECI(self, ignore_sizes=(0,), interactive=True):

@@ -1133,3 +1116,3 @@ """Plot the all the ECI.

pred = self.eci.dot(cf)
pred = self.get_eci().dot(cf)

@@ -1172,7 +1155,9 @@ if row.get("final_struct_id", -1) != -1:

if self.scoring_scheme == "loocv":
cv = self.loocv() * 1000.0
cv = self.loocv()
elif self.scoring_scheme == "loocv_fast":
cv = self.loocv_fast() * 1000.0
cv = self.loocv_fast()
elif self.scoring_scheme == "k-fold":
cv = self.k_fold_cv() * 1000.0
cv = self.k_fold_cv()
else:
raise ValueError(f"Unknown scoring scheme: {self.schoring_scheme}")
return cv

@@ -1186,30 +1171,5 @@

"""
if self.eci is None:
raise ValueError("ECIs have not been fitted yet.")
return self.cf_matrix.dot(self.eci)
eci = self.get_eci()
return self.cf_matrix.dot(eci)
def subtract_predict_dft(self) -> np.ndarray:
"""
Subtract CE predicted energy from DFT energy
:return: Energy difference between DFT and CE model
(i.e., E_DFT - E_CE) in the original unit (typically eV)
"""
e_pred = self.get_energy_predict()
delta_e = self.e_dft - e_pred
return delta_e
def subtract_predict_dft_loo(self) -> Optional[np.ndarray]:
"""
Subtract CE predicted energy from DFT energy in the leave-one-out
scheme.
:return: Energy difference between DFT and CE model
(i.e., E_DFT - E_CE_LOO) in the original unit (typically eV)
"""
if self.e_pred_loo is None:
return None
delta_e_loo = self.e_dft - self.e_pred_loo
return delta_e_loo
def get_eci_by_size(self) -> Dict[str, Dict[str, list]]:

@@ -1275,4 +1235,12 @@ """

cv = evaluator.k_fold_cv()
num_eci = len(np.nonzero(evaluator.get_eci(allow_fit=True))[0])
evaluator.fit()
num_eci = len(np.nonzero(evaluator.get_eci())[0])
logger.info("%.10f\t %d\t %.10f", alpha, num_eci, cv)
return cv
def supports_alpha_cv(scheme: LinearRegression) -> bool:
"""Determine whether a regression scheme supports alpha CV"""
if scheme.is_scalar() and hasattr(scheme, "alpha"):
return True
return False

@@ -79,2 +79,3 @@ """Monte Carlo method for ase."""

self.reset_averagers()
self._reset_internal_counters()

@@ -183,3 +184,2 @@ def update_current_energy(self) -> None:

ms_per_step = 1000.0 * self.status_every_sec / (self.current_step - prev)
accept_rate = self.num_accepted / self.current_step
logger.info(

@@ -190,3 +190,3 @@ "%d of %d steps. %.2f ms per step. Acceptance rate: %.2f",

ms_per_step,
accept_rate,
self.current_accept_rate,
)

@@ -261,2 +261,10 @@ prev = self.current_step

@property
def current_accept_rate(self) -> float:
"""Return the current accept rate as a value between 0 and 1."""
if self.current_step == 0:
# No steps have been taken yet.
return 0.0
return self.num_accepted / self.current_step
def get_thermodynamic_quantities(self):

@@ -271,2 +279,3 @@ """Compute thermodynamic quantities."""

quantities["temperature"] = self.temperature
quantities["accept_rate"] = self.current_accept_rate
at_count = self.count_atoms()

@@ -273,0 +282,0 @@ for key, value in at_count.items():

@@ -6,2 +6,3 @@ from typing import List, Tuple

from clease import Evaluate, ConvexHull
from clease.evaluate import supports_alpha_cv

@@ -28,6 +29,6 @@

plot_args = {}
X = evaluate.get_energy_predict()
Y = evaluate.e_dft
xlabel = plot_args.get("xlabel", "E_CE (eV/atom)")
ylabel = plot_args.get("ylabel", "E_DFT (eV/atom)")
X = evaluate.e_dft
Y = evaluate.get_energy_predict()
xlabel = plot_args.get("xlabel", "E_DFT (eV/atom)")
ylabel = plot_args.get("ylabel", "E_CE (eV/atom)")
title = plot_args.get("title", f"Fit using {len(evaluate.e_dft)} data points.")

@@ -51,3 +52,3 @@

cv = evaluate.get_cv_score()
cv = evaluate.get_cv_score() * 1000
rmse = evaluate.rmse() * 1000

@@ -92,3 +93,5 @@

def plot_fit_residual(evaluate: Evaluate, plot_args: dict = None) -> Figure:
def plot_fit_residual(
evaluate: Evaluate, plot_args: dict = None, interactive: bool = False
) -> Figure:
"""

@@ -112,3 +115,4 @@ Figure object subtracted (DFT) and predicted energies.

X = evaluate.e_dft
Y = evaluate.subtract_predict_dft()
Y = evaluate.get_energy_predict() - X # eV/atom
Y *= 1000 # meV/atom
xlabel = plot_args.get("xlabel", "#OCC")

@@ -120,6 +124,7 @@ ylabel = plot_args.get("ylabel", r"$E_{DFT} - E_{pred}$ (meV/atom)")

fig, ax = plt.subplots(ncols=2, sharey=True, gridspec_kw=gridspec_kw)
ax[0].axhline(0, ls="--")
plot_line = ax[0].plot(X, Y, "v", mfc="none")[0]
ax[0].set_xlabel(r"$E_{DFT}$ (eV/atom)")
ax[0].set_ylabel(ylabel)
ax[0].set_title(title)
ax[0].set_ylabel(ylabel)
ax[0].axhline(0, ls="--")
ax[0].plot(X, Y, "v", mfc="none")

@@ -133,2 +138,18 @@ hist, bin_edges = np.histogram(Y, bins=30)

if interactive:
# pylint: disable=import-outside-toplevel
from clease.interactive_plot import ShowStructureOnClick, AnnotatedAx
annotations = _make_annotations_plot_fit(evaluate)
# Construct the annotated axis objects.
annotated_ax = AnnotatedAx(
ax[0],
[plot_line],
annotations,
structure_names=[evaluate.names],
)
# Attach interactivity to the fig object.
ShowStructureOnClick(fig, annotated_ax, evaluate.settings.db_name)
return fig

@@ -202,2 +223,4 @@

"""
if not supports_alpha_cv(evaluate.scheme):
raise ValueError(f"Scheme {evaluate.scheme!r} doesn't support alpha CV.")
if plot_args is None:

@@ -204,0 +227,0 @@ plot_args = {}

@@ -58,2 +58,6 @@ from typing import Tuple

"""
if len(self.alpha) != X.shape[1]:
msg = "Alpha has wrong number of dimensions. It should be equal to the number "
msg += f"of features {X.shape[1]}, but got {len(self.alpha)}."
raise ValueError(msg)
if self._constraint is None:

@@ -60,0 +64,0 @@ return X.T.dot(X) + self.alpha, X.T.dot(y)

@@ -10,3 +10,3 @@ from typing import List, Sequence, Dict, Union, Callable, Tuple

from clease.data_normalizer import DataNormalizer
from clease.tools import split_dataset
from clease.tools import split_dataset, get_size_from_cf_name
from .regression import LinearRegression

@@ -69,2 +69,5 @@ from .constrained_ridge import ConstrainedRidge

is recommended to put normalize=False for such cases.
:param cf_names: List of strings, used to initialize the size and diameters
which will be used.
"""

@@ -79,2 +82,3 @@

normalize: bool = True,
cf_names: List[str] = None,
) -> None:

@@ -91,2 +95,5 @@ super().__init__()

self._constraint = None
if cf_names is not None:
self.diameters_from_names(cf_names)
self.sizes_from_names(cf_names)

@@ -144,3 +151,3 @@ def add_constraint(self, A: np.ndarray, c: np.ndarray) -> None:

"""
self.sizes = [int(n[1]) for n in names]
self.sizes = [get_size_from_cf_name(n) for n in names]

@@ -158,3 +165,4 @@ def diameters_from_names(self, names: List[str]) -> None:

for n in names:
if n[1] == "0" or n[1] == "1":
size = get_size_from_cf_name(n)
if size in {0, 1}:
diameters.append(0.0)

@@ -161,0 +169,0 @@ else:

@@ -11,3 +11,2 @@ """Definition of ClusterExpansionSettings Class.

from deprecated import deprecated
import numpy as np

@@ -62,6 +61,2 @@ from ase import Atoms

max_cluster_size (int | None, optional): Deprecated. Specifies the maximum cluster
body size. Defaults to None. A DeprecationWarning will be raised,
if this value is not None.
max_cluster_dia (Sequence[float], optional): A list of int or float containing the

@@ -107,5 +102,2 @@ maximum diameter of clusters (in Å). Defaults to ``(5., 5., 5.)``, i.e.

db_name: str = "clease.db",
# max_cluster_size is only here for deprecation purposes
# if it is not None, the user has manually specified a value
max_cluster_size=None,
max_cluster_dia: Sequence[float] = (5.0, 5.0, 5.0),

@@ -150,5 +142,3 @@ include_background_atoms: bool = False,

self.max_cluster_dia = _format_max_cluster_dia(
max_cluster_dia, max_cluster_size=max_cluster_size
)
self.max_cluster_dia = np.array(max_cluster_dia)

@@ -691,3 +681,4 @@ self.basis_func_type = basis_func_type

# For compatibility, since it's no longer in KWARG_KEYS
kwargs["max_cluster_size"] = dct.pop("max_cluster_size")
# Avoid crashing.
dct.pop("max_cluster_size")

@@ -753,50 +744,2 @@ settings = cls(*args, **kwargs)

def _format_max_cluster_dia(max_cluster_dia, max_cluster_size=None):
"""Formatter of max_cluster_dia."""
if max_cluster_size is None and not isinstance(max_cluster_dia, (int, float)):
# Assume max_cluster_dia is sequence[float], and user didn't specify any
# (now deprecated) max_cluster sizes.
return np.array(max_cluster_dia)
return _old_format_max_cluster_dia(max_cluster_dia, max_cluster_size)
def _old_format_max_cluster_dia(max_cluster_dia, max_cluster_size):
# User specified an old version of MCS and MCD
dep_msg = f"""
max_cluser_size should no longer be specfied explicitly,
and max_cluster_dia should no longer be an int or float.
Specify cluster sizes with max_cluster_dia as an array-like instead.
Got max_cluster_size '{max_cluster_size}' and max_cluster_dia '{max_cluster_dia}'.
Try instead to use max_cluster_dia as an array, e.g. max_cluster_dia=[5., 5., 5.]
for 2-, 3- and 4-body clusters of cutoff 5 Å.
"""
@deprecated(version="0.10.6", reason=dep_msg)
def _formatter():
# max_cluster_dia is list or array
if isinstance(max_cluster_dia, (list, np.ndarray, tuple)):
# Length should be either max_cluster_size+1 or max_cluster_size-1
mcd = np.array(max_cluster_dia, dtype=float)
if len(max_cluster_dia) == max_cluster_size + 1:
# Remove the first two entries, assume they are 0- and 1-body diameters
mcd = mcd[2:]
elif len(max_cluster_dia) == max_cluster_size - 1:
# Assume max_cluster_dia contains 2+ body clusters
pass
else:
raise ValueError("Invalid length for max_cluster_dia.")
elif isinstance(max_cluster_dia, (int, float)):
if max_cluster_size is None:
raise ValueError("Received no max_cluster_size, but a float for max_cluster_dia")
mcd = np.ones(max_cluster_size - 1, dtype=float) * max_cluster_dia
# Case for *None* or something else
else:
raise TypeError(f"max_cluster_dia is of wrong type, got: {type(max_cluster_dia)}")
return mcd.round(decimals=3)
return _formatter()
def _get_prim_cell_id_from_connection(prim_cell: Atoms, connection: Database) -> int:

@@ -803,0 +746,0 @@ """Retrieve the primitive cell ID from a database connection"""

@@ -54,2 +54,4 @@ .. testsetup::

>>> from clease import Evaluate
>>> import clease.plot_post_process as pp
>>> import matplotlib.pyplot as plt
>>>

@@ -64,7 +66,10 @@ >>> eva = Evaluate(settings=settings, scoring_scheme='k-fold', nsplits=10)

>>> eva.set_fitting_scheme(fitting_scheme='l1', alpha=alpha)
>>> eva.plot_fit(interactive=False)
>>> eva.fit() # Run the fit with these settings.
>>>
>>> fig = pp.plot_fit(eva)
>>> plt.show()
>>>
>>> # plot ECI values
>>> eva.plot_ECI()
>>>
>>> fig = pp.plot_eci(eva)
>>> plt.show()
>>> # save a dictionary containing cluster names and their ECIs

@@ -71,0 +76,0 @@ >>> eva.save_eci(fname='eci_l1')

@@ -7,2 +7,24 @@ .. _releasenotes:

1.0.0
======
* 21 June 2022 - CLEASE is no longer considered beta.
* :class:`~clease.evaluate.Evaluate` can now properly support fitting with custom LinearRegression
schemes, even if they don't support alpha cross-validation.
* :class:`~clease.evaluate.Evaluate` now required explicit calls to
:py:meth:`~clease.evaluate.Evaluate.fit`. Calls to :py:meth:`~clease.evaluate.Evaluate.get_eci`
and :py:meth:`~clease.evaluate.Evaluate.get_eci_dict` can no longer implicitly do fitting.
This un-does a change introduced in version 0.11.6.
* Added the :py:attr:`~clease.montecarlo.montecarlo.Montecarlo.current_accept_rate` property,
and export the current accept rate in the thermodynamic quantities dictionary under the
``accept_rate`` key.
* Removed a series of deprecated things:
* Removed the ``clease.concentration`` module.
* Removed the ``clease.new_struct`` module.
* Removed old regression imports. Regression classes must now be imported from the
``clease.regression`` module.
* Removed the ``clease.structure_generator`` module.
* Removed the ``max_cluster_size`` settings argument.
0.11.6

@@ -9,0 +31,0 @@ =======

Metadata-Version: 2.1
Name: clease
Version: 0.11.6
Version: 1.0.0
Summary: CLuster Expansion in Atomistic Simulation Environment

@@ -12,3 +12,3 @@ Home-page: https://gitlab.com/computationalmaterials/clease/

Keywords: Cluster Expansion,Monte Carlo,Computational materials,Materials research
Classifier: Development Status :: 4 - Beta
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)

@@ -15,0 +15,0 @@ Classifier: Programming Language :: Python :: 3.7

@@ -20,3 +20,3 @@ [metadata]

classifiers =
Development Status :: 4 - Beta
Development Status :: 5 - Production/Stable
License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)

@@ -23,0 +23,0 @@ Programming Language :: Python :: 3.7

from deprecated import deprecated
from . import settings
__all__ = ("Concentration",)
@deprecated(version="0.10.0", reason="Use Concentration class from clease.settings instead")
class Concentration(settings.Concentration):
"""Concentration class was moved to clease.settings"""
"""Deprecated import of new_struct.
Module has been moved to clease.structgen, so
use clease.structgen.new_struct instead """
from warnings import warn
from deprecated import deprecated
import numpy as np
from clease.structgen import new_struct
MSG = "Import {} from clease.structgen.new_struct instead"
DEP_VERSION = "0.10.2" # Deprecation version
MODULE_DEP_MSG = f"""
The clease.new_struct module has been moved as of version {DEP_VERSION}.
Please use the clease.structgen.new_struct module instead"""
# Print the message on import
warn(MODULE_DEP_MSG, np.VisibleDeprecationWarning)
@deprecated(version=DEP_VERSION, reason=MSG.format("NewStructures"))
class NewStructures(new_struct.NewStructures):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("MaxAttemptReachedError"))
class MaxAttemptReachedError(new_struct.MaxAttemptReachedError):
pass
"""Module for defining deprecated regression class imports"""
# pylint: skip-file
from deprecated import deprecated
from clease import regression
__all__ = (
"LinearRegression",
"Tikhonov",
"Lasso",
"BayesianCompressiveSensing",
"ConstrainedRidge",
"GAFit",
"GeneralizedRidgeRegression",
"PhysicalRidge",
"SequentialClusterRidge",
)
MSG = "Import {} from clease.regression instead"
DEP_VERSION = "0.10.0" # Deprecation version
@deprecated(version=DEP_VERSION, reason=MSG.format("LinearRegression"))
class LinearRegression(regression.LinearRegression):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("Tikhonov"))
class Tikhonov(regression.Tikhonov):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("Lasso"))
class Lasso(regression.Lasso):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("BayesianCompressiveSensing"))
class BayesianCompressiveSensing(regression.BayesianCompressiveSensing):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("ConstrainedRidge"))
class ConstrainedRidge(regression.ConstrainedRidge):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("GAFit"))
class GAFit(regression.GAFit):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("GeneralizedRidgeRegression"))
class GeneralizedRidgeRegression(regression.GeneralizedRidgeRegression):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("PhysicalRidge"))
class PhysicalRidge(regression.PhysicalRidge):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("SequentialClusterRidge"))
class SequentialClusterRidge(regression.SequentialClusterRidge):
pass
"""Deprecated import of structure_generator.
Module has been moved to clease.structgen, so
use clease.structgen.structure_generator instead"""
from warnings import warn
from deprecated import deprecated
import numpy as np
from clease.structgen import structure_generator
MSG = "Import {} from clease.structgen.structure_generator instead"
DEP_VERSION = "0.10.2" # Deprecation version
MODULE_DEP_MSG = f"""
The clease.new_struct module has been moved as of version {DEP_VERSION}.
Please use the clease.structgen.structure_generator module instead"""
# Print the message on import
warn(MODULE_DEP_MSG, np.VisibleDeprecationWarning)
@deprecated(version=DEP_VERSION, reason=MSG.format("StructureGenerator"))
class StructureGenerator(structure_generator.StructureGenerator):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("GSStructure"))
class GSStructure(structure_generator.GSStructure):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("MetropolisTrajectory"))
class MetropolisTrajectory(structure_generator.MetropolisTrajectory):
pass
@deprecated(version=DEP_VERSION, reason=MSG.format("ProbeStructure"))
class ProbeStructure(structure_generator.ProbeStructure):
pass

Sorry, the diff of this file is too big to display