Skip to content

aravind-uom/bluehill-tensile-analysis

Repository files navigation

Bluehill Tensile Analysis

License: MIT Python 3.9+

A general-purpose analysis and figure generation tool for tensile test data exported from Instron universal testing machines using Bluehill software.

For each tensile specimen, the tool computes Young's modulus, upper yield stress and strain, cold-drawing plateau stress, elongation at break, UTS, and toughness from raw Bluehill .csv exports. It then generates a standard set of publication-quality figures — stress–strain grids, overlays, and mechanical property summary plots — configurable for any two-additive polymer composite system.

All study-specific settings (file paths, formulation names, additive levels, colours, figure layout) live in a single config.py file. The analysis code itself contains no material- or project-specific references.


Cite this software

If you use this tool in published work, please cite both the software and the original study for which it was developed:

Software:

[JOSS citation to follow upon publication]

Original study (PEO–TA–GO composite):

Powar A, Ismail A, Vijayaraghavan A, Iliut M (2025).
Brittle-to-Ductile Transition and Exceptional Toughness in Ultra-High Molecular
Weight PEO–Tannic Acid–Graphene Oxide Composite Films with Recyclable Mechanical
Performance. Advanced Composites and Hybrid Materials.
[preprint DOI to follow]

Requirements

Package Minimum version
Python 3.9
NumPy 1.21
SciPy 1.7
Matplotlib 3.5
Pandas 1.3

Install all dependencies:

pip install -r requirements.txt

Or with conda:

conda install numpy scipy matplotlib pandas

Quick start

Option 1 — Your own data

  1. Edit config.py — set DATA_DIRS, OUT_DIR, and define your formulations in SAMPLE_DEFS. See Configuration below.
  2. Run:
    python bluehill_tensile_analysis.py

Option 2 — Reproduce the PEO–TA–GO paper figures

cp config_peo_ta_go.py config.py
# edit DATA_DIRS and OUT_DIR in config.py to point to your copy of the raw data
python bluehill_tensile_analysis.py

Data Format

Directory structure

The script expects Bluehill's default export folder structure. Each formulation is exported to a sub-folder named <formulation_name>.is_tens_Exports/, containing one .csv file per specimen:

<DATA_DIR>/
    Neat_Polymer.is_tens_Exports/
        Neat_Polymer_1.csv
        Neat_Polymer_2.csv
        Neat_Polymer_3.csv
    Polymer_5TA.is_tens_Exports/
        Polymer_5TA_1.csv
        Polymer_5TA_2.csv
    Polymer_5TA_0.5GO.is_tens_Exports/
        ...

The folder names you use (e.g. Neat_Polymer, Polymer_5TA) must exactly match the folder_name field in SAMPLE_DEFS in config.py.

CSV format

Each .csv file is a Bluehill export with a variable-length header block followed by columnar data. The script locates the data section automatically by finding the row beginning with Time. The columns read are:

Column index Content Units
3 Tensile stress MPa
5 Tensile strain (crosshead) %

Other columns are ignored. If your Bluehill export uses different column ordering, update the column indices in load_csv() in bluehill_core.py.


Configuration

All settings are in config.py. The file is divided into nine numbered sections with inline documentation. Key sections:

Section 1 — Data paths

DATA_DIRS = {
    'series_a': '/path/to/virgin_data',
    'series_b': '/path/to/recycled_data',   # omit if single series
}
OUT_DIR = '/path/to/output'

Section 4 — Formulation definitions

Each formulation is one tuple in SAMPLE_DEFS:

SAMPLE_DEFS = [
    # (modifier1_wt%, modifier2_wt%, folder_name,       regime,    series_name)
    (0,   0,    'Neat_Polymer',                         'brittle', 'series_a'),
    (5,   0,    'Polymer_5mod1',                        'draw',    'series_a'),
    (5,   0.5,  'Polymer_5mod1_0.5mod2',                'draw',    'series_a'),
    (5,   1,    'Polymer_5mod1_1mod2',                  'draw',    'series_a'),
    (10,  0,    'Polymer_10mod1',                       'draw',    'series_a'),
]
  • modifier1_wt% — the first additive (e.g. a plasticiser); becomes the row variable in panel figures
  • modifier2_wt% — the second additive (e.g. a filler); becomes the x-axis in property summary plots
  • regime'brittle', 'draw', or 'stiff' (informational only; does not affect any calculation)
  • series_name — must match a key in DATA_DIRS

Section 5 — Additive values and colours

ADDITIVE_VALS   = [0, 0.5, 1, 2, 5]           # modifier2 levels tested
ADDITIVE_COLORS = {0: '#444444', 0.5: '#5BC8E2', ...}
ADDITIVE_LABELS = {0: '0 wt% GO', 0.5: '0.5 wt% GO', ...}

Sections 6–9 — Study structure, figure layout, and output filenames

See the inline comments in config.py for full documentation of these sections.


Worked example: PEO–TA–GO composite study

config_peo_ta_go.py is a complete, commented configuration for the study described in Powar et al. (2025). It demonstrates how to set up a two-modifier, two-series study with five additive loadings across eleven formulations per series.

Material system:

  • Base polymer: ultra-high molecular weight poly(ethylene oxide) (PEO)
  • Modifier 1: tannic acid (TA) at 2 and 4 wt%
  • Modifier 2: graphene oxide (GO) at 0, 0.5, 1, 2, and 5 wt%
  • Two series: virgin (as-cast) and recycled (dissolution-recast)

Three mechanical regimes observed:

  • Regime I ('brittle'): fracture below 20% strain — pure PEO baseline
  • Regime II ('draw'): cold-drawing to large elongation — TA-modified, low GO
  • Regime III ('stiff'): stiffened cold-drawing — 5 wt% GO

Output figures

The script generates up to twelve PNG figures, depending on how many series and modifier levels are configured. Output filenames are set in FIGURE_FILENAMES in config.py.

Figure type Content
SS_*_panels.png Grid of all replicate curves (rows = modifier1 levels, columns = additive loadings)
SS_*_overlay.png Two-panel overlay by additive loading for a single modifier1 level (initial region + full curve)
SS_reference.png All replicates of the baseline / reference formulation
Props_*.png 6-panel property summary: E, σ_y, σ_draw, UTS, ε_b, U vs. additive content
Comparison_*.png Series A vs. B comparison for a given modifier1 level
SS_representative_panels.png Multi-panel figure: one representative curve per formulation

Adapting the script

Adding a new formulation

Add a tuple to SAMPLE_DEFS in config.py and create the corresponding Bluehill export folder:

SAMPLE_DEFS = [
    ...
    (5, 3, 'Polymer_5mod1_3mod2', 'draw', 'series_a'),   # new intermediate loading
]

Add the new additive value to ADDITIVE_VALS and assign it a colour in ADDITIVE_COLORS.

Adding a new modifier1 level

Add the value to MODIFIER_LEVELS, add an entry to MODIFIER_STYLES, and add the corresponding formulations to SAMPLE_DEFS.

Changing the elastic modulus window

The modulus regression window (0.3–2.5% strain) is defined in compute_modulus():

lo, hi = 0.003, 0.025   # fractional strain (multiply by 100 for %)

Adjust these bounds if your material has a different linear-elastic range.

Changing the cold-draw plateau definition

The plateau window (yield_idx + 8 to yield_idx + 80) is in compute_draw_stress(). The bounds reflect data acquired at ~10–20 Hz at 50 mm/min with a 25 mm gauge length. For different acquisition rates or speeds, adjust to span approximately the first 5–10% of the cold-drawing plateau.

Changing output resolution

SAVE_DPI = 600   # in config.py — higher DPI increases file size substantially

Excluding specimens

Specimens can be excluded globally (same exclusion applied to every series) or per-series (different exclusions for each series). Both forms are accepted by OUTLIERS in config.py:

# Flat set — excludes these filenames from ALL series
OUTLIERS = {'Formulation_A_2.csv', 'Formulation_B_1.csv'}

# Dict — excludes different specimens per series (recommended for multi-series studies)
OUTLIERS = {
    'series_a': {'Formulation_A_2.csv'},   # excluded from series_a only
    'series_b': {'Formulation_B_1.csv'},   # excluded from series_b only
}

Both forms accept the same filename-based exclusion syntax. Use the dict form when a specimen should be excluded from one series (e.g. recycled) but not another (e.g. virgin).


Algorithm notes

Fracture detection

find_fracture_idx() uses two criteria to handle both fracture modes robustly. The ductile trigger (last point above 0.30 MPa) prevents including the zero-load noise tail after specimen separation. The brittle trigger (stress dropping to below 10% of peak within 15 points of the peak) correctly identifies catastrophic fracture and avoids integrating the post-fracture noise tail into toughness. Both thresholds were validated against a dataset of 110+ specimens. For materials with very different stiffness or at significantly different testing speeds, these may need recalibration.

Yield point identification

find_upper_yield() applies Savitzky–Golay smoothing (window 9, order 2) to the stress signal before searching for the first local maximum. Savitzky–Golay filtering is used in preference to moving averages because it preserves peak positions and heights. A ±5-point neighbourhood search in the raw (unsmoothed) signal then recovers the true yield stress without the systematic reduction introduced by smoothing.

Representative specimen selection

find_representative_idx() selects the specimen closest to the formulation mean in a z-scored three-property space {E, ε_b, U}. This three-property criterion is preferable to single-property selection (e.g. mean modulus alone) because it identifies the specimen that is simultaneously typical in stiffness, ductility, and energy absorption.


Reproducibility

  • All figures for the PEO–TA–GO study were generated with the exact script version archived in this repository.
  • The OUTLIERS dict in config_peo_ta_go.py documents all three excluded specimens and the reason for each (pre-loaded virgin PEO specimen; premature fracture in virgin 2TA-2GO; grip slippage in recycled 2TA-5GO).
  • Figure dimensions and font sizes are set so that text is ≥ 7 pt when reproduced at final journal column width (~85 mm single column / ~170 mm double column).

Licence

MIT License. See LICENSE for full text.


Authors

Aravind Vijayaraghavan and Maria Iliut Department of Materials and National Graphene Institute, The University of Manchester, UK

Acknowledgements

This tool was originally developed for the PEO–TA–GO composite study (Powar et al., 2025). Contributions for other material systems are welcome via pull request.

About

Analysis pipeline for tensile test data exported from Instron Bluehill systems

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages