Shear¶
__init__(self, folder, id_row=None, stress_col=None, strain_col=None, header=0, strain1=0.05, strain2=0.15, expect_yield=True)
special
¶
Tensile test class.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
folder |
Union[pathlib.Path, str] |
String or Path-like folder containing test data. |
required |
id_row |
Optional[int] |
Row number of the specimen ID. Most test machines export a headed csv file with some metadata like date, test method name etc. Specimen ID should be contained in this section. If not passed, pymechtest will use the filename as the specimen ID. |
None |
stress_col |
Optional[str] |
Name of the column containing stress data. If not passed, pymechtest will try to autodetect it from your data. |
None |
strain_col |
Optional[str] |
Name of the column containing strain data. If not passed, pymechtest will try to autodetect it from your data. |
None |
header |
int |
0-indexed row number of the table header (i.e. the row containing things like "Stress", "Strain", "Load" etc.). Defaults to 0. |
0 |
strain1 |
float |
Lower strain bound for modulus calculation. Must be in %. Defaults to 0.05. |
0.05 |
strain2 |
float |
Upper strain bound for modulus calculation. Must be in %. Defaults to 0.15. |
0.15 |
expect_yield |
bool |
Whether the specimens are expected to be elastic to failure (False) or they are expected to have a yield strength (True). Defaults to True. |
True |
Source code in pymechtest/shear.py
def __init__(
self,
folder: Union[Path, str],
id_row: Optional[int] = None,
stress_col: Optional[str] = None,
strain_col: Optional[str] = None,
header: int = 0,
strain1: float = 0.05,
strain2: float = 0.15,
expect_yield: bool = True,
) -> None:
"""
Tensile test class.
Args:
folder (Union[Path, str]): String or Path-like folder containing
test data.
id_row (int, optional): Row number of the specimen ID.
Most test machines export a headed csv file with some
metadata like date, test method name etc. Specimen ID
should be contained in this section. If not passed, pymechtest
will use the filename as the specimen ID.
stress_col (str, optional): Name of the column containing stress data.
If not passed, pymechtest will try to autodetect it from your data.
strain_col (str, optional): Name of the column containing strain data.
If not passed, pymechtest will try to autodetect it from your data.
header (int, optional): 0-indexed row number of the table header
(i.e. the row containing things like "Stress", "Strain", "Load" etc.).
Defaults to 0.
strain1 (float, optional): Lower strain bound for modulus calculation.
Must be in %. Defaults to 0.05.
strain2 (float, optional): Upper strain bound for modulus calculation.
Must be in %. Defaults to 0.15.
expect_yield (bool, optional): Whether the specimens are expected to be
elastic to failure (False) or they are expected to have a
yield strength (True). Defaults to True.
"""
super().__init__(
folder=folder,
id_row=id_row,
stress_col=stress_col,
strain_col=strain_col,
header=header,
strain1=strain1,
strain2=strain2,
expect_yield=expect_yield,
)
load_all(self)
inherited
¶
Loads all the found files in 'folder' into a dataframe.
Recursively searches 'folder' for all csv files, grabs the specimen identifier specified during 'id_row' and includes this in the dataframe.
Returns:
Type | Description |
---|---|
DataFrame |
pd.DataFrame: All found test data with specimen identifier. |
Source code in pymechtest/shear.py
def load_all(self) -> pd.DataFrame:
"""
Loads all the found files in 'folder' into a dataframe.
Recursively searches 'folder' for all csv files, grabs the specimen identifier
specified during 'id_row' and includes this in the dataframe.
Returns:
pd.DataFrame: All found test data with specimen identifier.
"""
# Cast to Path so can glob even if user passed str
fp = Path(self.folder).resolve()
df = (
(pd.concat([self._load(f) for f in sorted(fp.rglob("*.csv"))]))
.assign(spec_id=lambda x: pd.Categorical(x["Specimen ID"]))
.drop(columns=["Specimen ID"])
.rename(columns={"spec_id": "Specimen ID"})
)
# Reorder the columns for OCD reasons
col = df.pop("Specimen ID")
df.insert(0, "Specimen ID", col)
return df
plot_curves(self, title=None, save_path=None, save_method='selenium', x_label=None, y_label=None, height=500, width=750)
inherited
¶
Creates a nice looking stress strain plot of all the specimens using altair.
Will use the class name to fill in axis labels if not passed, e.g 'Tensile' Strain
Parameters:
Name | Type | Description | Default |
---|---|---|---|
title |
Optional[str] |
Title for the plot. Defaults to "{class_name} Stress-Strain Curves". |
None |
save_path |
Union[str, pathlib.Path] |
str or Pathlike path to save a png of the plot. Requires chrome and selenium. If not passed, plot is simply returned and not saved. |
None |
save_method |
Optional[str] |
One of 2 altair save methods: 'selenium' or 'node'. if 'selenium' requires a configured geckodriver or chromedriver on PATH. if 'node' requires nodejs installation. Defaults to 'selenium' |
'selenium' |
x_label |
Optional[str] |
Label for x-axis. Defaults to "{class name}Strain (%)". |
None |
y_label |
Optional[str] |
Label for y-axis. Defaults to "{class name}Stress (MPa)". |
None |
height |
int |
Height of the plot. Defaults to 500. |
500 |
width |
int |
Width of the plot. Defaults to 750. |
750 |
Returns:
Type | Description |
---|---|
Chart |
alt.Chart: Stress strain plot. |
Source code in pymechtest/shear.py
def plot_curves(
self,
title: Optional[str] = None,
save_path: Optional[Union[str, Path]] = None,
save_method: Optional[str] = "selenium",
x_label: Optional[str] = None,
y_label: Optional[str] = None,
height: int = 500,
width: int = 750,
) -> alt.Chart:
"""
Creates a nice looking stress strain plot of all the specimens using altair.
Will use the class name to fill in axis labels if not passed, e.g
'Tensile' Strain
Args:
title (str, optional): Title for the plot.
Defaults to "{class_name} Stress-Strain Curves".
save_path (Union[str, Path], optional): str or Pathlike path to save
a png of the plot. Requires chrome and selenium. If not passed, plot
is simply returned and not saved.
save_method (str, optional): One of 2 altair save methods:
'selenium' or 'node'.
if 'selenium' requires a configured geckodriver or chromedriver on PATH.
if 'node' requires nodejs installation. Defaults to 'selenium'
x_label (str, optional): Label for x-axis.
Defaults to "{class name}Strain (%)".
y_label (str, optional): Label for y-axis.
Defaults to "{class name}Stress (MPa)".
height (int, optional): Height of the plot.
Defaults to 500.
width (int, optional): Width of the plot.
Defaults to 750.
Returns:
alt.Chart: Stress strain plot.
"""
# Altair will warn if over 5,000 rows in a notebook. This is cleanest solution.
alt.data_transformers.enable("data_server")
if not x_label:
x_label = f"{self.__class__.__qualname__} Strain (%)"
if not y_label:
y_label = f"{self.__class__.__qualname__} Stress (MPa)"
if not title:
title = f"{self.__class__.__qualname__} Stress Strain Curves"
df = self.load_all()
chart = (
alt.Chart(data=df)
.mark_line(size=1)
.encode(
x=alt.X(f"{self.strain_col}:Q", title=x_label),
y=alt.Y(f"{self.stress_col}:Q", title=y_label),
color=alt.Color("Specimen ID:N", title="Specimen ID"),
)
.properties(title=title, height=height, width=width)
)
if save_method not in set(["selenium", "node"]):
raise ValueError(
f"Save method must be one of 'selenium' or 'node'. Got: {save_method}"
)
if save_path:
fp = Path(save_path).resolve()
save(
chart,
fp=str(fp),
scale_factor=6.0,
method=save_method,
)
return chart
stats(self)
inherited
¶
Returns a table of summary statistics e.g. mean, std, cov etc. for the data in folder.
Uses pandas df.describe() to do the bulk of the work, just adds in cov for good measure.
Returns:
Type | Description |
---|---|
DataFrame |
pd.DataFrame: Summary statistics. |
Source code in pymechtest/shear.py
def stats(self) -> pd.DataFrame:
"""
Returns a table of summary statistics e.g. mean, std, cov etc.
for the data in folder.
Uses pandas df.describe() to do the bulk of the work, just adds in
cov for good measure.
Returns:
pd.DataFrame: Summary statistics.
"""
df = self.summarise().describe()
df.loc["cov%"] = df.loc["std"] / df.loc["mean"] * 100
# Reorganise so cov is close to std
new_index = ["count", "mean", "std", "cov%", "min", "25%", "50%", "75%", "max"]
df = df.reindex(new_index)
return df
summarise(self)
inherited
¶
High level summary method, generates a dataframe containing key test values such as UTS, Modulus etc. for all the data in the target folder.
Returns:
Type | Description |
---|---|
DataFrame |
pd.DataFrame: Dataframe containing test summary values for each specimen. |
Source code in pymechtest/shear.py
def summarise(self) -> pd.DataFrame:
"""
High level summary method, generates a dataframe containing key
test values such as UTS, Modulus etc. for all the data in the
target folder.
Returns:
pd.DataFrame: Dataframe containing test summary values for each
specimen.
"""
fp = Path(self.folder).resolve()
rows = [
self._extract_values(df)
for df in [self._load(f) for f in sorted(fp.rglob("*.csv"))]
]
# .T transposes to that it's the expected dataframe format
return (pd.concat(rows, axis=1, ignore_index=True).T).convert_dtypes()