Options
PASCal.options
¶
This module defines the options used by the PASCal library/app when fitting strain and volume data.
Classes¶
PASCalDataType (Enum)
¶
Options
dataclass
¶
Options(data_type: PASCal.options.PASCalDataType, eulerian_strain: bool = True, finite_strain: bool = True, use_pc: bool = False, pc_val: Optional[float] = None, deg_poly_strain: int = 5, deg_poly_vol: int = 5)
Source code in PASCal/options.py
@dataclass
class Options:
data_type: PASCalDataType = field(
metadata={
"form": "DataType",
},
)
"""The type of data passed, either 'Pressure', 'Electrochemical' or 'Temperature'."""
eulerian_strain: bool = field(
default=True,
metadata={
"form": "EulerianStrain",
},
)
"""Whether to use Eulerian strain (True) or Lagrangian"""
finite_strain: bool = field(default=True, metadata={"form": "FiniteStrain"})
"""Whether to use finite strain (True) or infinitesimal strain"""
use_pc: bool = field(
default=False,
metadata={
"form": "UsePc",
},
)
"""Whether to use the critical pressure to modify the fits."""
pc_val: Optional[float] = field(
default=None,
metadata={
"form": "PcVal",
},
)
"""The critical pressure value to use in GPa."""
deg_poly_strain: int = field(
default=5,
metadata={
"form": "DegPolyCap",
},
)
"""The degree of polynomial to use for fitting the strain vs charge/capacity."""
deg_poly_vol: int = field(
default=5,
metadata={
"form": "DegPolyVol",
},
)
"""The degree of polynomial to use for fitting the volume vs charge/capacity"""
@staticmethod
def from_dict(options: Dict[str, Any]) -> "Options":
"""Load options from a dictionary."""
if options.get("data_type"):
options["data_type"] = PASCalDataType[options["data_type"].upper()]
if options.get("pc_val") is not None:
if not options.get("pc_val"):
options["pc_val"] = None
else:
options["pc_val"] = float(options["pc_val"])
if options.get("pc_val") is None:
options["use_pc"] = False
if options.get("deg_poly_strain"):
options["deg_poly_strain"] = int(options["deg_poly_strain"])
if options.get("deg_poly_vol"):
options["deg_poly_vol"] = int(options["deg_poly_vol"])
return Options(**options)
@staticmethod
def from_form(form_data: Dict[str, str]) -> "Options":
"""Go through and check the values provided by the form."""
options = {}
for key in fields(Options):
form_key = key.metadata["form"]
if form_key in form_data:
value = True if form_data[form_key] == "True" else form_data[form_key]
value = False if form_data[form_key] == "False" else value
options[key.name] = value
return Options.from_dict(options)
def precheck_inputs(self, x) -> List[str]:
"""Check that the raw data passed is compatible with the options, adjusting
the options where possible.
Returns:
A list of warnings, if any.
"""
if len(x) < 2:
raise RuntimeError("Too few data points to perform fit: need at least 2")
warning: List[str] = []
if self.data_type == PASCalDataType.PRESSURE:
if len(x) < 4:
warning.append(
"At least as many data points as parameters are needed for a fit to be carried out (e.g. 3 for 3rd order Birch-Murnaghan, 4 for empirical pressure fitting). "
"As PASCal calculates errors from derivatives, more data points than parameters are needed for error estimates."
)
if self.use_pc and self.pc_val:
if np.amin(x) < self.pc_val:
pc_val: float = np.min(x)
warning.append(
"The critical pressure has to be smaller than the lower pressure data point. "
f"Critical pressure has been set to the minimum value: {pc_val} GPa."
)
self.pc_val = pc_val
if self.data_type == PASCalDataType.ELECTROCHEMICAL:
if len(x) - 2 < self.deg_poly_strain:
deg_poly_strain = len(x) - 2
warning.append(
f"The maximum degree of the Chebyshev strain polynomial has been lowered from {self.deg_poly_strain} to {deg_poly_strain}. "
"At least as many data points as parameters are needed for a fit to be carried out. "
"As PASCal calculates errors from derivatives, more data points than parameters are needed for error estimates."
)
self.deg_poly_strain = deg_poly_strain
if len(x) - 2 < self.deg_poly_vol:
deg_poly_vol = len(x) - 2
warning.append(
f"The maximum degree of the Chebyshev volume polynomial has been lowered from {self.deg_poly_vol} to {deg_poly_vol}. "
"At least as many data points as parameters are needed for a fit to be carried out. "
"As PASCal calculates errors from derivatives, more data points than parameters are needed for error estimates."
)
self.deg_poly_vol = deg_poly_vol
return warning
Attributes¶
data_type: PASCalDataType
dataclass-field
¶
The type of data passed, either 'Pressure', 'Electrochemical' or 'Temperature'.
eulerian_strain: bool
dataclass-field
¶
Whether to use Eulerian strain (True) or Lagrangian
finite_strain: bool
dataclass-field
¶
Whether to use finite strain (True) or infinitesimal strain
use_pc: bool
dataclass-field
¶
Whether to use the critical pressure to modify the fits.
pc_val: Optional[float]
dataclass-field
¶
The critical pressure value to use in GPa.
deg_poly_strain: int
dataclass-field
¶
The degree of polynomial to use for fitting the strain vs charge/capacity.
deg_poly_vol: int
dataclass-field
¶
The degree of polynomial to use for fitting the volume vs charge/capacity
Methods¶
from_dict(options: Dict[str, Any]) -> Options
staticmethod
¶
Load options from a dictionary.
Source code in PASCal/options.py
@staticmethod
def from_dict(options: Dict[str, Any]) -> "Options":
"""Load options from a dictionary."""
if options.get("data_type"):
options["data_type"] = PASCalDataType[options["data_type"].upper()]
if options.get("pc_val") is not None:
if not options.get("pc_val"):
options["pc_val"] = None
else:
options["pc_val"] = float(options["pc_val"])
if options.get("pc_val") is None:
options["use_pc"] = False
if options.get("deg_poly_strain"):
options["deg_poly_strain"] = int(options["deg_poly_strain"])
if options.get("deg_poly_vol"):
options["deg_poly_vol"] = int(options["deg_poly_vol"])
return Options(**options)
from_form(form_data: Dict[str, str]) -> Options
staticmethod
¶
Go through and check the values provided by the form.
Source code in PASCal/options.py
@staticmethod
def from_form(form_data: Dict[str, str]) -> "Options":
"""Go through and check the values provided by the form."""
options = {}
for key in fields(Options):
form_key = key.metadata["form"]
if form_key in form_data:
value = True if form_data[form_key] == "True" else form_data[form_key]
value = False if form_data[form_key] == "False" else value
options[key.name] = value
return Options.from_dict(options)
precheck_inputs(self, x) -> List[str]
¶
Check that the raw data passed is compatible with the options, adjusting the options where possible.
Returns:
Type | Description |
---|---|
List[str] |
A list of warnings, if any. |
Source code in PASCal/options.py
def precheck_inputs(self, x) -> List[str]:
"""Check that the raw data passed is compatible with the options, adjusting
the options where possible.
Returns:
A list of warnings, if any.
"""
if len(x) < 2:
raise RuntimeError("Too few data points to perform fit: need at least 2")
warning: List[str] = []
if self.data_type == PASCalDataType.PRESSURE:
if len(x) < 4:
warning.append(
"At least as many data points as parameters are needed for a fit to be carried out (e.g. 3 for 3rd order Birch-Murnaghan, 4 for empirical pressure fitting). "
"As PASCal calculates errors from derivatives, more data points than parameters are needed for error estimates."
)
if self.use_pc and self.pc_val:
if np.amin(x) < self.pc_val:
pc_val: float = np.min(x)
warning.append(
"The critical pressure has to be smaller than the lower pressure data point. "
f"Critical pressure has been set to the minimum value: {pc_val} GPa."
)
self.pc_val = pc_val
if self.data_type == PASCalDataType.ELECTROCHEMICAL:
if len(x) - 2 < self.deg_poly_strain:
deg_poly_strain = len(x) - 2
warning.append(
f"The maximum degree of the Chebyshev strain polynomial has been lowered from {self.deg_poly_strain} to {deg_poly_strain}. "
"At least as many data points as parameters are needed for a fit to be carried out. "
"As PASCal calculates errors from derivatives, more data points than parameters are needed for error estimates."
)
self.deg_poly_strain = deg_poly_strain
if len(x) - 2 < self.deg_poly_vol:
deg_poly_vol = len(x) - 2
warning.append(
f"The maximum degree of the Chebyshev volume polynomial has been lowered from {self.deg_poly_vol} to {deg_poly_vol}. "
"At least as many data points as parameters are needed for a fit to be carried out. "
"As PASCal calculates errors from derivatives, more data points than parameters are needed for error estimates."
)
self.deg_poly_vol = deg_poly_vol
return warning