BET - Brunauer-Emmett-Teller
Brunauer-Emmett-Teller (BET) analysis is used to measure the specific surface area, pore volume, and pore size distribution of solid materials via gas adsorption. It provides key physical properties related to material reactivity and processing behavior.
Method Overview
| Property | Value |
|---|---|
| Full Name | Brunauer-Emmett-Teller Surface Area Analysis |
| Purpose | Measures surface area, pore volume, and pore size distribution |
| Adsorptive Gas | Nitrogen (N2) at 77K |
| SharePoint Location | Analytical Data > BET |
| File Format | CSV (instrument export) |
Key Metrics
| Metric | Units | Description |
|---|---|---|
| AS(BET) | m²/g | Specific surface area via BET method |
| AS(BETMP) | m²/g | Multi-point BET surface area |
| Total Pore Volume | cm³/g | Total pore volume at specified p/p0 |
| Average Pore Diameter | nm | Average pore diameter |
| C-Value | dimensionless | BET constant (adsorption energy indicator) |
Pore Size Classification
| Classification | Diameter Range |
|---|---|
| Micropores | < 2 nm |
| Mesopores | 2-50 nm |
| Macropores | > 50 nm |
Data Pipeline
SharePoint Sources
| Type | Site | Folders | Files |
|---|---|---|---|
| BET Data | Analytical Data | BET, BET Data | .csv |
File naming pattern: {sample_id} - BET Data Output.csv
Dagster Assets
The BET data pipeline consists of the following assets in apps/datasmart/src/datasmart/assets/analytical/bet.py:
bet_tables (sharepoint_multi_asset)
├── bet_params_incremental (backend.bet_params_incremental)
└── bet_raw (analytical.bet_raw)
↓
bet (analytical.bet)
↓
bet_simplified (analytical.bet_simplified)
Asset Descriptions
| Asset | Schema | Description |
|---|---|---|
bet_params_incremental | backend | Melted parameter data from CSV files |
bet_raw | analytical | Raw isotherm data points |
bet | analytical | Wide format, 1 row per sample with all parameters |
bet_simplified | analytical | Key metrics only, C > 0 filtered, replicates averaged |
Database Tables
analytical.bet_raw
Raw isotherm data points from BET measurements.
| Column | Type | Description |
|---|---|---|
sample_id | string | Normalized sample ID |
original_sample_id | string | Raw sample ID from filename |
No | integer | Data point number |
p/p0 | float | Relative pressure |
p/Va(p0-p) | float | BET transform value |
file_id | string | SharePoint file identifier |
analytical.bet
Wide format table with all BET parameters.
| Column | Type | Description |
|---|---|---|
sample_id | string | Normalized sample ID |
original_sample_id | string | Raw sample ID |
analysis_date | datetime | Date of analysis |
operator | string | Operator who performed analysis |
as(bet) | float | BET surface area (m²/g) |
as(betmp) | float | Multi-point BET surface area (m²/g) |
c | float | BET C constant |
total_pore_volume | float | Total pore volume (cm³/g) |
average_pore_diameter | float | Average pore diameter (nm) |
p/p0 | float | Relative pressure for pore calculation |
instrument | string | Instrument name |
s/n | string | Serial number |
analysis_port | string | Analysis port used |
sample_mass | float | Sample mass (g) |
adsorptive | string | Adsorptive gas type |
adsorption_data_point_number | integer | Number of adsorption points |
desorption_data_point_number | integer | Number of desorption points |
analytical.bet_simplified
Simplified table with key metrics only.
| Column | Type | Description |
|---|---|---|
sample_id | string | Normalized sample ID |
as(bet) | float | BET surface area (m²/g) |
total_pore_volume | float | Total pore volume (cm³/g) |
average_pore_diameter | float | Average pore diameter (nm) |
p/p0 | float | Relative pressure |
File Format
CSV Structure
BET CSV files contain two sections:
- Parameters section: Key-value pairs with parameter, value, and units columns
- Raw data section: Isotherm data starting with "No" header
Example structure:
Instrument,BELSorp Mini II,
S/N,xxxxx,
Analysis date,2024-01-15,
Operator,John Doe,
Sample mass,0.1234,g
...
AS(BET),12.345,m²/g
Total pore volume at p/p0=0.99,0.0567,cm³/g
C,89.12,
...
No,p/p0,p/Va(p0-p)
1,0.05,0.123
2,0.10,0.234
...
C-Value Validation
The BET C constant indicates the validity of the measurement:
| C Value | Interpretation |
|---|---|
| C > 0 | Valid measurement |
| C < 0 | Poor fit, non-ideal adsorption |
| Very large C | Potential issues with measurement |
The bet_simplified asset automatically filters for measurements where C > 0.
Usage Examples
Query Simplified Data
from shared.db.sql import SQL
# Get simplified BET data (recommended for most analyses)
bet = SQL.read("""
SELECT sample_id, "as(bet)", total_pore_volume, average_pore_diameter
FROM analytical.bet_simplified
WHERE sample_id LIKE 'P800%'
""")
Query Full BET Data
# Get full BET data with all parameters
full_bet = SQL.read("""
SELECT sample_id, original_sample_id, analysis_date, operator,
"as(bet)", c, total_pore_volume, average_pore_diameter,
instrument, sample_mass
FROM analytical.bet
WHERE sample_id IS NOT NULL
ORDER BY analysis_date DESC
""")
Query Isotherm Data
# Get raw isotherm data for plotting
isotherm = SQL.read("""
SELECT "No", "p/p0", "p/Va(p0-p)"
FROM analytical.bet_raw
WHERE sample_id = 'P800-001-1-QBND-FM'
ORDER BY "No"
""")
Plot BET Isotherm
import matplotlib.pyplot as plt
isotherm = SQL.read("""
SELECT "p/p0", "p/Va(p0-p)"
FROM analytical.bet_raw
WHERE sample_id = 'P800-001-1-QBND-FM'
ORDER BY "No"
""")
plt.figure(figsize=(10, 6))
plt.plot(isotherm["p/p0"], isotherm["p/Va(p0-p)"], 'o-')
plt.xlabel("Relative Pressure (p/p0)")
plt.ylabel("p/Va(p0-p)")
plt.title("BET Isotherm")
plt.grid(True, alpha=0.3)
plt.show()
Join with XRF Data
# Combine BET with XRF for material characterization
combined = SQL.read("""
SELECT
b.sample_id,
b."as(bet)" as surface_area,
b.total_pore_volume,
b.average_pore_diameter,
x.CaO, x.MgO, x.SiO2
FROM analytical.bet_simplified b
LEFT JOIN analytical.xrf_simplified x
ON b.sample_id = x.sample_id
WHERE b.sample_id IS NOT NULL
""")
Sample ID Processing
The pipeline uses the SampleID class to normalize sample identifiers:
from data_infrastructure.sample_id import SampleID
# Normalize sample IDs
df = SampleID.update_sample_id(
df,
is_material=True,
project_team_map=project_team_map,
crosswalk=sample_id_crosswalk,
)
Related Assets
| Asset | Description |
|---|---|
sample_id_crosswalk | Maps messy sample IDs to canonical format |
project_team_map | Maps old process area codes to new project team codes |
Troubleshooting
Missing Samples
If a sample is missing from BET tables:
- Check if the source CSV exists in SharePoint under
BET/BET Data/ - Verify the file naming follows
{sample_id} - BET Data Output.csv - Check
backend.bet_params_incrementalfor raw data
Invalid C Values
If samples are missing from bet_simplified:
- Check the
cvalue inanalytical.bet- must be > 0 - Negative or zero C values indicate measurement issues
- Contact the analytical team for re-measurement if needed
# Find samples filtered out due to C value
SQL.read("""
SELECT sample_id, "as(bet)", c
FROM analytical.bet
WHERE c <= 0
""")
Sample ID Normalization Issues
If sample IDs aren't matching:
- Check
original_sample_idcolumn for the raw value - Review
sample_id_crosswalkfor applicable mappings - Update crosswalk if a new mapping is needed